diff --git a/ch5/.lock b/ch5/.lock old mode 100755 new mode 100644 diff --git a/ch5/SourceSerif4-Bold.ttf.woff2 b/ch5/SourceSerif4-Bold.ttf.woff2 deleted file mode 100644 index db57d214..00000000 Binary files a/ch5/SourceSerif4-Bold.ttf.woff2 and /dev/null differ diff --git a/ch5/SourceSerif4-It.ttf.woff2 b/ch5/SourceSerif4-It.ttf.woff2 deleted file mode 100644 index 1cbc021a..00000000 Binary files a/ch5/SourceSerif4-It.ttf.woff2 and /dev/null differ diff --git a/ch5/SourceSerif4-Regular.ttf.woff2 b/ch5/SourceSerif4-Regular.ttf.woff2 deleted file mode 100644 index 2db73fe2..00000000 Binary files a/ch5/SourceSerif4-Regular.ttf.woff2 and /dev/null differ diff --git a/ch5/ayu.css b/ch5/ayu.css deleted file mode 100644 index f98b3417..00000000 --- a/ch5/ayu.css +++ /dev/null @@ -1 +0,0 @@ - :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;}.slider{background-color:#ccc;}.slider:before{background-color:white;}input:focus+.slider{box-shadow:0 0 0 2px #0a84ff,0 0 0 6px rgba(10,132,255,0.3);}h1,h2,h3,h4{color:white;}h1.fqn a{color:#fff;}h4{border:none;}.in-band{background-color:#0f1419;}.docblock code{color:#ffb454;}.code-header{color:#e6e1cf;}.docblock pre>code,pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}pre,.rustdoc.source .example-wrap{color:#e6e1cf;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);}.sidebar .current,.sidebar a:hover{background-color:transparent;color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock table td,.docblock table th{border-color:#5c6773;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#000 !important;background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ffa0a5;}.content span.union,.content a.union{color:#ffa0a5;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#39AFD7;}.content span.primitive,.content a.primitive{color:#ffa0a5;}.content span.traitalias,.content a.traitalias{color:#39AFD7;}.content span.keyword,.content a.keyword{color:#39AFD7;}.content span.externcrate,.content span.mod,.content a.mod{color:#39AFD7;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#ffa0a5;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#39AFD7;}.content span.type,.content a.type,.block a.current.type{color:#39AFD7;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#39AFD7;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}.sidebar a{color:#53b1db;}.sidebar a.current.type{color:#53b1db;}.sidebar a.current.associatedtype{color:#53b1db;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#39AFD7;}.sidebar h2 a,.sidebar h3 a{color:white;}.search-results a{color:#0096cf;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before{color:#999;}details.rustdoc-toggle>summary::before{filter:invert(100%);}#crate-search,.search-input{background-color:#141920;border-color:#424c57;}#crate-search{border-color:#424c57 !important;}.search-input{color:#ffffff;}.module-item .stab,.import-item .stab{color:#000;}.stab.empty-impl{}.stab.must_implement{}.stab.unstable,.stab.deprecated,.stab.portability,.stab.empty-impl,.stab.must_implement{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background:none;}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label,.code-attribute{color:#999;}:target{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip::after{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip::before{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}.notable-traits-tooltiptext .notable{border-bottom-color:#5c6773;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>button:hover,#titles>button.selected{}.content span.typedef,.content a.typedef,.block a.current.typedef{}.content span.union,.content a.union,.block a.current.union{}pre.rust .lifetime{}.stab.unstable{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content a.attr,.content a.derive,.content a.macro{}.stab.portability{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}.search-results a:focus span{}a.result-trait:focus{}a.result-traitalias:focus{}a.result-mod:focus,a.result-externcrate:focus{}a.result-mod:focus{}a.result-externcrate:focus{}a.result-enum:focus{}a.result-struct:focus{}a.result-union:focus{}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{}a.result-type:focus{}a.result-associatedtype:focus{}a.result-foreigntype:focus{}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{}a.result-constant:focus,a.result-static:focus{}a.result-primitive:focus{}a.result-keyword:focus{}.sidebar a.current.enum{}.sidebar a.current.struct{}.sidebar a.current.foreigntype{}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{}.sidebar a.current.union{}.sidebar a.current.constant .sidebar a.current.static{}.sidebar a.current.primitive{}.sidebar a.current.externcrate .sidebar a.current.mod{}.sidebar a.current.trait{}.sidebar a.current.traitalias{}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{}.sidebar a.current.keyword{}@media (max-width:700px){.sidebar-elems{border-right-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow:inset 0 -1px 0 #5c6773;}#settings-menu>a,#help-button>button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#settings-menu>a img{filter:invert(100);}.popover,.popover::before,#help-button span.top,#help-button span.bottom{border-color:#5c6773;}#copy-path{color:#fff;}#copy-path>img{filter:invert(70%);}#copy-path:hover>img{filter:invert(100%);}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>button:hover,#help-button>button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}.search-results .result-name span.alias{color:#c5c5c5;}.search-results .result-name span.grey{color:#999;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:#14191f;color:#ffb44c;}#source-sidebar div.files>a.selected{background-color:#14191f;color:#ffb44c;}.scraped-example-list .scrape-help{border-color:#aaa;color:#eee;}.scraped-example-list .scrape-help:hover{border-color:white;color:white;}.more-examples-toggle summary,.more-examples-toggle .hide-more{color:#999;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(15,20,25,1),rgba(15,20,25,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(15,20,25,1),rgba(15,20,25,0));}.toggle-line-inner{background:#999;}.toggle-line:hover .toggle-line-inner{background:#c5c5c5;} \ No newline at end of file diff --git a/ch5/dark.css b/ch5/dark.css deleted file mode 100644 index 242423d0..00000000 --- a/ch5/dark.css +++ /dev/null @@ -1 +0,0 @@ -:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;}.slider{background-color:#ccc;}.slider:before{background-color:white;}input:focus+.slider{box-shadow:0 0 0 2px #0a84ff,0 0 0 6px rgba(10,132,255,0.3);}.in-band{background-color:#353535;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff)}.sidebar .current,.sidebar a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock table td,.docblock table th{border-color:#ddd;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#eee !important;background-color:#616161;}.search-results a:focus span{color:#eee !important;}a.result-trait:focus{background-color:#013191;}a.result-traitalias:focus{background-color:#013191;}a.result-mod:focus,a.result-externcrate:focus{background-color:#884719;}a.result-enum:focus{background-color:#194e9f;}a.result-struct:focus{background-color:#194e9f;}a.result-union:focus{background-color:#194e9f;}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{background-color:#4950ed;}a.result-type:focus{background-color:#194e9f;}a.result-associatedtype:focus{background-color:#884719;}a.result-foreigntype:focus{background-color:#194e9f;}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{background-color:#217d1c;}a.result-constant:focus,a.result-static:focus{background-color:#884719;}a.result-primitive:focus{background-color:#194e9f;}a.result-keyword:focus{background-color:#884719;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#2dbfb8;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#2dbfb8;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#D2991D;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#2dbfb8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#2dbfb8;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#D2991D;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2dbfb8;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#D2991D;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b78cf2;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#D2991D;}.sidebar a{color:#fdbf35;}.sidebar a.current.enum{color:#12ece2;}.sidebar a.current.struct{color:#12ece2;}.sidebar a.current.type{color:#12ece2;}.sidebar a.current.associatedtype{color:#fdbf35;}.sidebar a.current.foreigntype{color:#12ece2;}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{color:#0be900;}.sidebar a.current.union{color:#12ece2;}.sidebar a.current.constant .sidebar a.current.static{color:#fdbf35;}.sidebar a.current.primitive{color:#12ece2;}.sidebar a.current.externcrate .sidebar a.current.mod{color:#fdbf35;}.sidebar a.current.trait{color:#cca7ff;}.sidebar a.current.traitalias{color:#cca7ff;}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{color:#32d479;}.sidebar a.current.keyword{color:#fdbf35;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#D2991D;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before{color:#999;}details.rustdoc-toggle>summary::before{filter:invert(100%);}#crate-search,.search-input{color:#111;background-color:#f0f0f0;border-color:#f0f0f0;}#crate-search{border-color:#f0f0f0 !important;}.search-input{border-color:#e0e0e0;}.search-input:focus{border-color:#008dfd;}.stab.empty-impl{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#ffc4c4;border-color:#db7b7b;color:#2f2f2f;}.stab.must_implement{background:#F3DFFF;border-color:#b07bdb;color:#2f2f2f;}.stab.portability{background:#F3DFFF;border-color:#b07bdb;color:#2f2f2f;}.stab.portability>code{background:none;}.rightside,.out-of-band{color:grey;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{color:#dedede;background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label,.code-attribute{color:#999;}:target{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;border-color:#000;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}.notable-traits-tooltiptext .notable{border-bottom-color:#d2d2d2;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-elems{border-right-color:#000;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow:inset 0 -1px 0 #c6cbd1;}#settings-menu>a,#help-button>button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>button:hover,#help-button>button:focus{border-color:#ffb900;}.popover,.popover::before,#help-button span.top,#help-button span.bottom{border-color:#d2d2d2;}#copy-path{color:#999;}#copy-path>img{filter:invert(50%);}#copy-path:hover>img{filter:invert(65%);}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}.search-results .result-name span.alias{color:#fff;}.search-results .result-name span.grey{color:#ccc;}#source-sidebar>.title{border-bottom-color:#ccc;}#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:#444;}#source-sidebar div.files>a.selected{background-color:#333;}.scraped-example-list .scrape-help{border-color:#aaa;color:#eee;}.scraped-example-list .scrape-help:hover{border-color:white;color:white;}.more-examples-toggle summary,.more-examples-toggle .hide-more{color:#999;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(53,53,53,1),rgba(53,53,53,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(53,53,53,1),rgba(53,53,53,0));}.toggle-line-inner{background:#999;}.toggle-line:hover .toggle-line-inner{background:#c5c5c5;} \ No newline at end of file diff --git a/ch5/down-arrow.svg b/ch5/down-arrow.svg deleted file mode 100644 index 35437e77..00000000 --- a/ch5/down-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ch5/help.html b/ch5/help.html new file mode 100644 index 00000000..26794106 --- /dev/null +++ b/ch5/help.html @@ -0,0 +1 @@ +
fn:
) to \
- restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
- enum
, trait
, type
, macro
, \
- and const
.","Search functions by type signature (e.g., vec -> usize
or \
- -> vec
)","Search multiple things at once by splitting your query with comma (e.g., \
- str,u8
or String,struct:Vec,test
)","You can look for items with an exact name by putting double quotes around \
- your request: \"string\"
","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="pub const CLOCK_FREQ: usize = 12500000;
pub const MEMORY_END: usize = 0x81000000;
Constants used in rCore for qemu
-Constants used in rCore for qemu
+pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
pub const KERNEL_STACK_SIZE: usize = _; // 8_192usize
pub const PAGE_SIZE_BITS: usize = 0xc;
pub const TRAMPOLINE: usize = _; // 18_446_744_073_709_547_520usize
pub const TRAP_CONTEXT: usize = _; // 18_446_744_073_709_543_424usize
pub const USER_STACK_SIZE: usize = _; // 8_192usize
Constants used in rCore
-Constants used in rCore
+pub use crate::board::CLOCK_FREQ;
pub use crate::board::MEMORY_END;
pub use crate::board::MMIO;
struct Stdout;
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
struct Stdout;
From<T> for U
chooses to do.
+The main module and entrypoint
+The main module and entrypoint
Various facilities of the kernels are implemented as submodules. The most important ones are:
trap
: Handles all cases of switching from userspace to the kerneltask
: Task managementsyscall
: System call handling and implementationmm
: Address map using SV39sync
:Wrap a static data structure inside it so that we are able to access it without any unsafe
.trap
: Handles all cases of switching from userspace to the kerneltask
: Task managementsyscall
: System call handling and implementationmm
: Address map using SV39sync
:Wrap a static data structure inside it so that we are able to access it without any unsafe
.The operating system also starts in this module. Kernel code starts
-executing from entry.asm
, after which rust_main()
is called to
+executing from entry.asm
, after which rust_main()
is called to
initialize various pieces of functionality. (See its source code for
details.)
We then call task::run_tasks()
and for the first time go to
+
We then call task::run_tasks()
and for the first time go to
userspace.
Constants used in rCore for qemu
-Constants used in rCore
-SBI console driver, for text output
-The panic handler
-Loading user applications into memory
-Memory management implementation
-SBI call wrappers
-Synchronization and interior mutability primitives
-Implementation of syscalls
-Task management implementation
-RISC-V timer-related functionality
-Trap handling functionality
-The panic handler
+pub fn get_num_app() -> usize
get app number
+struct APP_NAMES {
+APP_NAMES in os::loader - Rust Expand description
All of app’s name
-Fields
__private_field: ()
Methods from Deref<Target = Vec<&'static str>>
1.0.0 · sourcepub fn capacity(&self) -> usize
Returns the number of elements the vector can hold without
+}Expand description
All of app’s name
+
Fields§
§__private_field: ()
Methods from Deref<Target = Vec<&'static str>>§
1.0.0 · sourcepub fn capacity(&self) -> usize
Returns the total number of elements the vector can hold without
reallocating.
Examples
-let vec: Vec<i32> = Vec::with_capacity(10);
-assert_eq!(vec.capacity(), 10);
-1.7.0 · sourcepub fn as_slice(&self) -> &[T]
Extracts a slice containing the entire vector.
+let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+1.7.0 · sourcepub fn as_slice(&self) -> &[T]
Extracts a slice containing the entire vector.
Equivalent to &s[..]
.
Examples
-use std::io::{self, Write};
-let buffer = vec![1, 2, 3, 5, 8];
-io::sink().write(buffer.as_slice()).unwrap();
-1.37.0 · sourcepub fn as_ptr(&self) -> *const T
Returns a raw pointer to the vector’s buffer, or a dangling raw pointer
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+1.37.0 · sourcepub fn as_ptr(&self) -> *const T
Returns a raw pointer to the vector’s buffer, or a dangling raw pointer
valid for zero sized reads if the vector didn’t allocate.
The caller must ensure that the vector outlives the pointer this
function returns, or else it will end up pointing to garbage.
@@ -20,166 +21,344 @@ Modifying the vector may cause its buffer to be reallocated,
which would also make any pointers to it invalid.
The caller must also ensure that the memory the pointer (non-transitively) points to
is never written to (except inside an UnsafeCell
) using this pointer or any pointer
-derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
+derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
+This method guarantees that for the purpose of the aliasing model, this method
+does not materialize a reference to the underlying slice, and thus the returned pointer
+will remain valid when mixed with other calls to as_ptr
and as_mut_ptr
.
+Note that calling other methods that materialize mutable references to the slice,
+or mutable references to specific elements you are planning on accessing through this pointer,
+as well as writing to those elements, may still invalidate this pointer.
+See the second example below for how this guarantee can be used.
Examples
-let x = vec![1, 2, 4];
-let x_ptr = x.as_ptr();
+let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
-unsafe {
- for i in 0..x.len() {
- assert_eq!(*x_ptr.add(i), 1 << i);
+unsafe {
+ for i in 0..x.len() {
+ assert_eq!(*x_ptr.add(i), 1 << i);
}
}
-
sourcepub fn allocator(&self) -> &A
🔬 This is a nightly-only experimental API. (allocator_api
)
Returns a reference to the underlying allocator.
-1.0.0 · sourcepub fn len(&self) -> usize
Returns the number of elements in the vector, also referred to
+
Due to the aliasing guarantee, the following code is legal:
+
+unsafe {
+ let mut v = vec![0, 1, 2];
+ let ptr1 = v.as_ptr();
+ let _ = ptr1.read();
+ let ptr2 = v.as_mut_ptr().offset(2);
+ ptr2.write(2);
+ // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+ // because it mutated a different element:
+ let _ = ptr1.read();
+}
+sourcepub fn allocator(&self) -> &A
🔬This is a nightly-only experimental API. (allocator_api
)
Returns a reference to the underlying allocator.
+1.0.0 · sourcepub fn len(&self) -> usize
Returns the number of elements in the vector, also referred to
as its ‘length’.
Examples
-let a = vec![1, 2, 3];
-assert_eq!(a.len(), 3);
-Methods from Deref<Target = [T]>
sourcepub fn sort_floats(&mut self)
🔬 This is a nightly-only experimental API. (sort_floats
)
Sorts the slice of floats.
-This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
-the ordering defined by f64::total_cmp
.
-Current implementation
-This uses the same sorting algorithm as sort_unstable_by
.
-Examples
-#![feature(sort_floats)]
-let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
-
-v.sort_floats();
-let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
-assert_eq!(&v[..8], &sorted[..8]);
-assert!(v[8].is_nan());
-Methods from Deref<Target = [T]>§
1.23.0 · sourcepub fn is_ascii(&self) -> bool
Checks if all bytes in this slice are within the ASCII range.
+sourcepub fn as_ascii(&self) -> Option<&[AsciiChar]>
🔬This is a nightly-only experimental API. (ascii_char
)
If this slice is_ascii
, returns it as a slice of
+ASCII characters, otherwise returns None
.
+sourcepub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]
🔬This is a nightly-only experimental API. (ascii_char
)
Converts this slice of bytes into a slice of ASCII characters,
+without checking whether they’re valid.
+Safety
+Every byte in the slice must be in 0..=127
, or else this is UB.
+1.23.0 · sourcepub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool
Checks that two slices are an ASCII case-insensitive match.
Same as to_ascii_lowercase(a) == to_ascii_lowercase(b)
,
but without allocating and copying temporaries.
-1.23.0 · sourcepub fn make_ascii_uppercase(&mut self)
Converts this slice to its ASCII upper case equivalent in-place.
+1.23.0 · sourcepub fn make_ascii_uppercase(&mut self)
Converts this slice to its ASCII upper case equivalent in-place.
ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’,
but non-ASCII letters are unchanged.
To return a new uppercased value without modifying the existing one, use
to_ascii_uppercase
.
-1.23.0 · sourcepub fn make_ascii_lowercase(&mut self)
Converts this slice to its ASCII lower case equivalent in-place.
+1.23.0 · sourcepub fn make_ascii_lowercase(&mut self)
Converts this slice to its ASCII lower case equivalent in-place.
ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’,
but non-ASCII letters are unchanged.
To return a new lowercased value without modifying the existing one, use
to_ascii_lowercase
.
-1.60.0 · sourcepub fn escape_ascii(&self) -> EscapeAscii<'_>
Returns an iterator that produces an escaped version of this slice,
+
1.60.0 · sourcepub fn escape_ascii(&self) -> EscapeAscii<'_>
sourcepub fn trim_ascii_start(&self) -> &[u8]
🔬 This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with leading ASCII whitespace bytes removed.
+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+sourcepub fn trim_ascii_start(&self) -> &[u8]
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with leading ASCII whitespace bytes removed.
+‘Whitespace’ refers to the definition used by
+u8::is_ascii_whitespace
.
+Examples
+#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b" ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+sourcepub fn trim_ascii_end(&self) -> &[u8]
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with trailing ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
Examples
-#![feature(byte_slice_trim_ascii)]
+#![feature(byte_slice_trim_ascii)]
-assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
-assert_eq!(b" ".trim_ascii_start(), b"");
-assert_eq!(b"".trim_ascii_start(), b"");
-
sourcepub fn trim_ascii_end(&self) -> &[u8]
🔬 This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with trailing ASCII whitespace bytes removed.
-‘Whitespace’ refers to the definition used by
-u8::is_ascii_whitespace
.
-Examples
-#![feature(byte_slice_trim_ascii)]
-
-assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
-assert_eq!(b" ".trim_ascii_end(), b"");
-assert_eq!(b"".trim_ascii_end(), b"");
-sourcepub fn trim_ascii(&self) -> &[u8]
🔬 This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with leading and trailing ASCII whitespace bytes
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b" ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+sourcepub fn trim_ascii(&self) -> &[u8]
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii
)
Returns a byte slice with leading and trailing ASCII whitespace bytes
removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
+Examples
+#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b" ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+sourcepub fn sort_floats(&mut self)
🔬This is a nightly-only experimental API. (sort_floats
)
Sorts the slice of floats.
+This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
+the ordering defined by f64::total_cmp
.
+Current implementation
+This uses the same sorting algorithm as sort_unstable_by
.
Examples
-#![feature(byte_slice_trim_ascii)]
+#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
-assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
-assert_eq!(b" ".trim_ascii(), b"");
-assert_eq!(b"".trim_ascii(), b"");
-
sourcepub fn flatten(&self) -> &[T]
🔬This is a nightly-only experimental API. (slice_flatten
)
Takes a &[[T; N]]
, and flattens it to a &[T]
.
+Panics
+This panics if the length of the resulting slice would overflow a usize
.
+This is only possible when flattening a slice of arrays of zero-sized
+types, and thus tends to be irrelevant in practice. If
+size_of::<T>() > 0
, this will never panic.
Examples
-let a = [1, 2, 3];
-assert_eq!(a.len(), 3);
-1.0.0 · sourcepub fn is_empty(&self) -> bool
Returns true
if the slice has a length of 0.
+#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+ [[1, 2, 3], [4, 5, 6]].flatten(),
+ [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+sourcepub fn flatten_mut(&mut self) -> &mut [T]
🔬This is a nightly-only experimental API. (slice_flatten
)
Takes a &mut [[T; N]]
, and flattens it to a &mut [T]
.
+Panics
+This panics if the length of the resulting slice would overflow a usize
.
+This is only possible when flattening a slice of arrays of zero-sized
+types, and thus tends to be irrelevant in practice. If
+size_of::<T>() > 0
, this will never panic.
Examples
-let a = [1, 2, 3];
-assert!(!a.is_empty());
-1.0.0 · sourcepub fn first(&self) -> Option<&T>
Returns the first element of the slice, or None
if it is empty.
+#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+ for i in slice {
+ *i += 5;
+ }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+sourcepub fn as_str(&self) -> &str
🔬This is a nightly-only experimental API. (ascii_char
)
Views this slice of ASCII characters as a UTF-8 str
.
+sourcepub fn as_bytes(&self) -> &[u8]
🔬This is a nightly-only experimental API. (ascii_char
)
Views this slice of ASCII characters as a slice of u8
bytes.
+sourcepub fn sort_floats(&mut self)
🔬This is a nightly-only experimental API. (sort_floats
)
Sorts the slice of floats.
+This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
+the ordering defined by f32::total_cmp
.
+Current implementation
+This uses the same sorting algorithm as sort_unstable_by
.
Examples
-let v = [10, 40, 30];
-assert_eq!(Some(&10), v.first());
+#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
-let w: &[i32] = &[];
-assert_eq!(None, w.first());
-
1.0.0 · sourcepub fn first_mut(&mut self) -> Option<&mut T>
Returns a mutable pointer to the first element of the slice, or None
if it is empty.
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+1.0.0 · sourcepub fn len(&self) -> usize
Returns the number of elements in the slice.
Examples
-let x = &mut [0, 1, 2];
-
-if let Some(first) = x.first_mut() {
- *first = 5;
-}
-assert_eq!(x, &[5, 1, 2]);
-1.5.0 · sourcepub fn split_first(&self) -> Option<(&T, &[T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
+let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+1.0.0 · sourcepub fn is_empty(&self) -> bool
Returns true
if the slice has a length of 0.
Examples
-let x = &[0, 1, 2];
-
-if let Some((first, elements)) = x.split_first() {
- assert_eq!(first, &0);
- assert_eq!(elements, &[1, 2]);
-}
-1.5.0 · sourcepub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
+let a = [1, 2, 3];
+assert!(!a.is_empty());
+1.0.0 · sourcepub fn first(&self) -> Option<&T>
Returns the first element of the slice, or None
if it is empty.
Examples
-let x = &mut [0, 1, 2];
+let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
-if let Some((first, elements)) = x.split_first_mut() {
- *first = 3;
- elements[0] = 4;
- elements[1] = 5;
-}
-assert_eq!(x, &[3, 4, 5]);
-
1.5.0 · sourcepub fn split_last(&self) -> Option<(&T, &[T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+1.0.0 · sourcepub fn first_mut(&mut self) -> Option<&mut T>
Returns a mutable pointer to the first element of the slice, or None
if it is empty.
Examples
-let x = &[0, 1, 2];
+let x = &mut [0, 1, 2];
-if let Some((last, elements)) = x.split_last() {
- assert_eq!(last, &2);
- assert_eq!(elements, &[0, 1]);
-}
-
1.5.0 · sourcepub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
+if let Some(first) = x.first_mut() {
+ *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+1.5.0 · sourcepub fn split_first(&self) -> Option<(&T, &[T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
Examples
-let x = &mut [0, 1, 2];
+let x = &[0, 1, 2];
-if let Some((last, elements)) = x.split_last_mut() {
- *last = 3;
- elements[0] = 4;
- elements[1] = 5;
-}
-assert_eq!(x, &[4, 5, 3]);
-
1.5.0 · sourcepub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
Examples
-let v = [10, 40, 30];
-assert_eq!(Some(&30), v.last());
+let x = &mut [0, 1, 2];
-let w: &[i32] = &[];
-assert_eq!(None, w.last());
-
1.0.0 · sourcepub fn last_mut(&mut self) -> Option<&mut T>
Returns a mutable pointer to the last item in the slice.
-Examples
-let x = &mut [0, 1, 2];
-
-if let Some(last) = x.last_mut() {
- *last = 10;
+if let Some((first, elements)) = x.split_first_mut() {
+ *first = 3;
+ elements[0] = 4;
+ elements[1] = 5;
}
-assert_eq!(x, &[0, 1, 10]);
-1.0.0 · sourcepub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
Returns a reference to an element or subslice depending on the type of
+assert_eq!(x, &[3, 4, 5]);
+1.5.0 · sourcepub fn split_last(&self) -> Option<(&T, &[T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
+Examples
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+ assert_eq!(last, &2);
+ assert_eq!(elements, &[0, 1]);
+}
+1.5.0 · sourcepub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
+Examples
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+ *last = 3;
+ elements[0] = 4;
+ elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+1.0.0 · sourcepub fn last(&self) -> Option<&T>
Returns the last element of the slice, or None
if it is empty.
+Examples
+let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+1.0.0 · sourcepub fn last_mut(&mut self) -> Option<&mut T>
Returns a mutable pointer to the last item in the slice.
+Examples
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+ *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+sourcepub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns the first N
elements of the slice, or None
if it has fewer than N
elements.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+sourcepub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns a mutable reference to the first N
elements of the slice,
+or None
if it has fewer than N
elements.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+ first[0] = 5;
+ first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+sourcepub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns the first N
elements of the slice and the remainder,
+or None
if it has fewer than N
elements.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+ assert_eq!(first, &[0, 1]);
+ assert_eq!(elements, &[2]);
+}
+sourcepub fn split_first_chunk_mut<const N: usize>(
+ &mut self
+) -> Option<(&mut [T; N], &mut [T])>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns a mutable reference to the first N
elements of the slice and the remainder,
+or None
if it has fewer than N
elements.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+ first[0] = 3;
+ first[1] = 4;
+ elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+sourcepub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns the last N
elements of the slice and the remainder,
+or None
if it has fewer than N
elements.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+ assert_eq!(last, &[1, 2]);
+ assert_eq!(elements, &[0]);
+}
+sourcepub fn split_last_chunk_mut<const N: usize>(
+ &mut self
+) -> Option<(&mut [T; N], &mut [T])>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+ last[0] = 3;
+ last[1] = 4;
+ elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+sourcepub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns the last element of the slice, or None
if it is empty.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+sourcepub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>
🔬This is a nightly-only experimental API. (slice_first_last_chunk
)
Returns a mutable pointer to the last item in the slice.
+Examples
+#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+ last[0] = 10;
+ last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+1.0.0 · sourcepub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where
+ I: SliceIndex<[T]>,
Returns a reference to an element or subslice depending on the type of
index.
- If given a position, returns a reference to the element at that
@@ -187,85 +366,97 @@ position or
None
if out of bounds.
- If given a range, returns the subslice corresponding to that range,
or
None
if out of bounds.
-Examples
-let v = [10, 40, 30];
-assert_eq!(Some(&40), v.get(1));
-assert_eq!(Some(&[10, 40][..]), v.get(0..2));
-assert_eq!(None, v.get(3));
-assert_eq!(None, v.get(0..4));
-1.0.0 · sourcepub fn get_mut<I>(
&mut self,
index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
Returns a mutable reference to an element or subslice depending on the
-type of index (see get
) or None
if the index is out of bounds.
-Examples
-let x = &mut [0, 1, 2];
+Examples
+let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · sourcepub fn get_mut<I>(
+ &mut self,
+ index: I
+) -> Option<&mut <I as SliceIndex<[T]>>::Output>where
+ I: SliceIndex<[T]>,
Returns a mutable reference to an element or subslice depending on the
+type of index (see get
) or None
if the index is out of bounds.
+Examples
+let x = &mut [0, 1, 2];
-if let Some(elem) = x.get_mut(1) {
- *elem = 42;
+if let Some(elem) = x.get_mut(1) {
+ *elem = 42;
}
-assert_eq!(x, &[0, 42, 2]);
-1.0.0 · sourcepub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
Returns a reference to an element or subslice, without doing bounds
+assert_eq!(x, &[0, 42, 2]);
+1.0.0 · sourcepub unsafe fn get_unchecked<I>(
+ &self,
+ index: I
+) -> &<I as SliceIndex<[T]>>::Outputwhere
+ I: SliceIndex<[T]>,
Returns a reference to an element or subslice, without doing bounds
checking.
-For a safe alternative see get
.
-Safety
-Calling this method with an out-of-bounds index is undefined behavior
-even if the resulting reference is not used.
-Examples
-let x = &[1, 2, 4];
-
-unsafe {
- assert_eq!(x.get_unchecked(1), &2);
-}
-1.0.0 · sourcepub unsafe fn get_unchecked_mut<I>(
&mut self,
index: I
) -> &mut <I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
Returns a mutable reference to an element or subslice, without doing
-bounds checking.
-For a safe alternative see get_mut
.
+For a safe alternative see get
.
Safety
Calling this method with an out-of-bounds index is undefined behavior
even if the resulting reference is not used.
-Examples
-let x = &mut [1, 2, 4];
+Examples
+let x = &[1, 2, 4];
-unsafe {
- let elem = x.get_unchecked_mut(1);
- *elem = 13;
+unsafe {
+ assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · sourcepub unsafe fn get_unchecked_mut<I>(
+ &mut self,
+ index: I
+) -> &mut <I as SliceIndex<[T]>>::Outputwhere
+ I: SliceIndex<[T]>,
Returns a mutable reference to an element or subslice, without doing
+bounds checking.
+For a safe alternative see get_mut
.
+Safety
+Calling this method with an out-of-bounds index is undefined behavior
+even if the resulting reference is not used.
+Examples
+let x = &mut [1, 2, 4];
+
+unsafe {
+ let elem = x.get_unchecked_mut(1);
+ *elem = 13;
}
-assert_eq!(x, &[1, 13, 4]);
-1.0.0 · sourcepub fn as_ptr(&self) -> *const T
Returns a raw pointer to the slice’s buffer.
The caller must ensure that the slice outlives the pointer this
function returns, or else it will end up pointing to garbage.
The caller must also ensure that the memory the pointer (non-transitively) points to
is never written to (except inside an UnsafeCell
) using this pointer or any pointer
-derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
+derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
Modifying the container referenced by this slice may cause its buffer
to be reallocated, which would also make any pointers to it invalid.
-Examples
-let x = &[1, 2, 4];
-let x_ptr = x.as_ptr();
+Examples
+let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
-unsafe {
- for i in 0..x.len() {
- assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+unsafe {
+ for i in 0..x.len() {
+ assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
}
}
-
1.0.0 · sourcepub fn as_mut_ptr(&mut self) -> *mut T
Returns an unsafe mutable pointer to the slice’s buffer.
+1.0.0 · sourcepub fn as_mut_ptr(&mut self) -> *mut T
Returns an unsafe mutable pointer to the slice’s buffer.
The caller must ensure that the slice outlives the pointer this
function returns, or else it will end up pointing to garbage.
Modifying the container referenced by this slice may cause its buffer
to be reallocated, which would also make any pointers to it invalid.
-Examples
-let x = &mut [1, 2, 4];
-let x_ptr = x.as_mut_ptr();
+Examples
+let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
-unsafe {
- for i in 0..x.len() {
- *x_ptr.add(i) += 2;
+unsafe {
+ for i in 0..x.len() {
+ *x_ptr.add(i) += 2;
}
}
-assert_eq!(x, &[3, 4, 6]);
-
1.48.0 · sourcepub fn as_ptr_range(&self) -> Range<*const T>
Returns the two raw pointers spanning the slice.
+assert_eq!(x, &[3, 4, 6]);
+1.48.0 · sourcepub fn as_ptr_range(&self) -> Range<*const T>
Returns the two raw pointers spanning the slice.
The returned range is half-open, which means that the end pointer
points one past the last element of the slice. This way, an empty
slice is represented by two equal pointers, and the difference between
the two pointers represents the size of the slice.
-See as_ptr
for warnings on using these pointers. The end pointer
+
See as_ptr
for warnings on using these pointers. The end pointer
requires extra caution, as it does not point to a valid element in the
slice.
This function is useful for interacting with foreign interfaces which
@@ -274,234 +465,185 @@ common in C++.
It can also be useful to check if a pointer to an element refers to an
element of this slice:
-let a = [1, 2, 3];
-let x = &a[1] as *const _;
-let y = &5 as *const _;
+let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
-assert!(a.as_ptr_range().contains(&x));
-assert!(!a.as_ptr_range().contains(&y));
-
1.48.0 · sourcepub fn as_mut_ptr_range(&mut self) -> Range<*mut T>
Returns the two unsafe mutable pointers spanning the slice.
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+1.48.0 · sourcepub fn as_mut_ptr_range(&mut self) -> Range<*mut T>
Returns the two unsafe mutable pointers spanning the slice.
The returned range is half-open, which means that the end pointer
points one past the last element of the slice. This way, an empty
slice is represented by two equal pointers, and the difference between
the two pointers represents the size of the slice.
-See as_mut_ptr
for warnings on using these pointers. The end
+
See as_mut_ptr
for warnings on using these pointers. The end
pointer requires extra caution, as it does not point to a valid element
in the slice.
This function is useful for interacting with foreign interfaces which
use two pointers to refer to a range of elements in memory, as is
common in C++.
-1.0.0 · sourcepub fn swap(&mut self, a: usize, b: usize)
Swaps two elements in the slice.
+If a
equals to b
, it’s guaranteed that elements won’t change value.
Arguments
- a - The index of the first element
- b - The index of the second element
-Panics
+Panics
Panics if a
or b
are out of bounds.
-Examples
-let mut v = ["a", "b", "c", "d", "e"];
-v.swap(2, 4);
-assert!(v == ["a", "b", "e", "d", "c"]);
-sourcepub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)
🔬 This is a nightly-only experimental API. (slice_swap_unchecked
)
sourcepub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)
🔬This is a nightly-only experimental API. (slice_swap_unchecked
)
Swaps two elements in the slice, without doing bounds checking.
+For a safe alternative see swap
.
Arguments
- a - The index of the first element
- b - The index of the second element
-Safety
+Safety
Calling this method with an out-of-bounds index is undefined behavior.
The caller has to ensure that a < self.len()
and b < self.len()
.
-Examples
-#![feature(slice_swap_unchecked)]
+Examples
+#![feature(slice_swap_unchecked)]
-let mut v = ["a", "b", "c", "d"];
-// SAFETY: we know that 1 and 3 are both indices of the slice
-unsafe { v.swap_unchecked(1, 3) };
-assert!(v == ["a", "d", "c", "b"]);
-
1.0.0 · sourcepub fn reverse(&mut self)
Reverses the order of elements in the slice, in place.
+Examples
+let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+1.0.0 · sourcepub fn iter(&self) -> Iter<'_, T>
Returns an iterator over the slice.
The iterator yields all items from start to end.
-Examples
-let x = &[1, 2, 4];
-let mut iterator = x.iter();
+Examples
+let x = &[1, 2, 4];
+let mut iterator = x.iter();
-assert_eq!(iterator.next(), Some(&1));
-assert_eq!(iterator.next(), Some(&2));
-assert_eq!(iterator.next(), Some(&4));
-assert_eq!(iterator.next(), None);
-
1.0.0 · sourcepub fn iter_mut(&mut self) -> IterMut<'_, T>
1.0.0 · sourcepub fn windows(&self, size: usize) -> Windows<'_, T>
Returns an iterator over all contiguous windows of length
size
. The windows overlap. If the slice is shorter than
size
, the iterator returns no values.
-Panics
+Panics
Panics if size
is 0.
-Examples
-let slice = ['r', 'u', 's', 't'];
-let mut iter = slice.windows(2);
-assert_eq!(iter.next().unwrap(), &['r', 'u']);
-assert_eq!(iter.next().unwrap(), &['u', 's']);
-assert_eq!(iter.next().unwrap(), &['s', 't']);
-assert!(iter.next().is_none());
+Examples
+let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
If the slice is shorter than size
:
-let slice = ['f', 'o', 'o'];
-let mut iter = slice.windows(4);
-assert!(iter.next().is_none());
-1.0.0 · sourcepub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+There’s no windows_mut
, as that existing would let safe code violate the
+“only one &mut
at a time to the same thing” rule. However, you can sometimes
+use Cell::as_slice_of_cells
in
+conjunction with windows
to accomplish something similar:
+
+use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+ Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+1.0.0 · sourcepub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last chunk will not have length chunk_size
.
-See chunks_exact
for a variant of this iterator that returns chunks of always exactly
-chunk_size
elements, and rchunks
for the same iterator but starting at the end of the
+
See chunks_exact
for a variant of this iterator that returns chunks of always exactly
+chunk_size
elements, and rchunks
for the same iterator but starting at the end of the
slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let mut iter = slice.chunks(2);
-assert_eq!(iter.next().unwrap(), &['l', 'o']);
-assert_eq!(iter.next().unwrap(), &['r', 'e']);
-assert_eq!(iter.next().unwrap(), &['m']);
-assert!(iter.next().is_none());
-1.0.0 · sourcepub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+
Examples
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+1.0.0 · sourcepub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
length of the slice, then the last chunk will not have length chunk_size
.
-See chunks_exact_mut
for a variant of this iterator that returns chunks of always
-exactly chunk_size
elements, and rchunks_mut
for the same iterator but starting at
+
See chunks_exact_mut
for a variant of this iterator that returns chunks of always
+exactly chunk_size
elements, and rchunks_mut
for the same iterator but starting at
the end of the slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
+Examples
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
-for chunk in v.chunks_mut(2) {
- for elem in chunk.iter_mut() {
- *elem += count;
+for chunk in v.chunks_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
}
- count += 1;
+ count += 1;
}
-assert_eq!(v, &[1, 1, 2, 2, 3]);
-
1.31.0 · sourcepub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+1.31.0 · sourcepub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
-resulting code better than in the case of chunks
.
-See chunks
for a variant of this iterator that also returns the remainder as a smaller
-chunk, and rchunks_exact
for the same iterator but starting at the end of the slice.
-Panics
+resulting code better than in the case of chunks
.
+See chunks
for a variant of this iterator that also returns the remainder as a smaller
+chunk, and rchunks_exact
for the same iterator but starting at the end of the slice.
+Panics
Panics if chunk_size
is 0.
-Examples
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let mut iter = slice.chunks_exact(2);
-assert_eq!(iter.next().unwrap(), &['l', 'o']);
-assert_eq!(iter.next().unwrap(), &['r', 'e']);
-assert!(iter.next().is_none());
-assert_eq!(iter.remainder(), &['m']);
-1.31.0 · sourcepub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+
Examples
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+1.31.0 · sourcepub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
length of the slice, then the last up to chunk_size-1
elements will be omitted and can be
retrieved from the into_remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
-resulting code better than in the case of chunks_mut
.
-See chunks_mut
for a variant of this iterator that also returns the remainder as a
-smaller chunk, and rchunks_exact_mut
for the same iterator but starting at the end of
+resulting code better than in the case of chunks_mut
.
+See chunks_mut
for a variant of this iterator that also returns the remainder as a
+smaller chunk, and rchunks_exact_mut
for the same iterator but starting at the end of
the slice.
-Panics
-Panics if chunk_size
is 0.
-Examples
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
-
-for chunk in v.chunks_exact_mut(2) {
- for elem in chunk.iter_mut() {
- *elem += count;
- }
- count += 1;
-}
-assert_eq!(v, &[1, 1, 2, 2, 0]);
-sourcepub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
-assuming that there’s no remainder.
-Safety
-This may only be called when
-
-- The slice splits exactly into
N
-element chunks (aka self.len() % N == 0
).
-N != 0
.
-
-Examples
-#![feature(slice_as_chunks)]
-let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
-let chunks: &[[char; 1]] =
- // SAFETY: 1-element chunks never have remainder
- unsafe { slice.as_chunks_unchecked() };
-assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
-let chunks: &[[char; 3]] =
- // SAFETY: The slice length (6) is a multiple of 3
- unsafe { slice.as_chunks_unchecked() };
-assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
-
-// These would be unsound:
-// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
-// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
-sourcepub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
-starting at the beginning of the slice,
-and a remainder slice with length strictly less than N
.
-Panics
-Panics if N
is 0. This check will most probably get changed to a compile time
-error before this method gets stabilized.
-Examples
-#![feature(slice_as_chunks)]
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let (chunks, remainder) = slice.as_chunks();
-assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
-assert_eq!(remainder, &['m']);
-sourcepub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
-starting at the end of the slice,
-and a remainder slice with length strictly less than N
.
Panics
-Panics if N
is 0. This check will most probably get changed to a compile time
-error before this method gets stabilized.
-Examples
-#![feature(slice_as_chunks)]
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let (remainder, chunks) = slice.as_rchunks();
-assert_eq!(remainder, &['l']);
-assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
-sourcepub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
🔬 This is a nightly-only experimental API. (array_chunks
)
Returns an iterator over N
elements of the slice at a time, starting at the
-beginning of the slice.
-The chunks are array references and do not overlap. If N
does not divide the
-length of the slice, then the last up to N-1
elements will be omitted and can be
-retrieved from the remainder
function of the iterator.
-This method is the const generic equivalent of chunks_exact
.
-Panics
-Panics if N
is 0. This check will most probably get changed to a compile time
-error before this method gets stabilized.
-Examples
-#![feature(array_chunks)]
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let mut iter = slice.array_chunks();
-assert_eq!(iter.next().unwrap(), &['l', 'o']);
-assert_eq!(iter.next().unwrap(), &['r', 'e']);
-assert!(iter.next().is_none());
-assert_eq!(iter.remainder(), &['m']);
-sourcepub unsafe fn as_chunks_unchecked_mut<const N: usize>(
&mut self
) -> &mut [[T; N]]
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+
Panics if chunk_size
is 0.
+Examples
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
+ }
+ count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+sourcepub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
assuming that there’s no remainder.
Safety
This may only be called when
@@ -509,751 +651,850 @@ assuming that there’s no remainder.
The slice splits exactly into N
-element chunks (aka self.len() % N == 0
).
N != 0
.
-Examples
-#![feature(slice_as_chunks)]
-let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
-let chunks: &mut [[char; 1]] =
- // SAFETY: 1-element chunks never have remainder
- unsafe { slice.as_chunks_unchecked_mut() };
-chunks[0] = ['L'];
-assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
-let chunks: &mut [[char; 3]] =
- // SAFETY: The slice length (6) is a multiple of 3
- unsafe { slice.as_chunks_unchecked_mut() };
-chunks[1] = ['a', 'x', '?'];
-assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+Examples
+#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+ // SAFETY: 1-element chunks never have remainder
+ unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+ // SAFETY: The slice length (6) is a multiple of 3
+ unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
-// These would be unsound:
-// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
-// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
-
sourcepub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+sourcepub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
starting at the beginning of the slice,
and a remainder slice with length strictly less than N
.
+Panics
+Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
+Examples
+#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+If you expect the slice to be an exact multiple, you can combine
+let
-else
with an empty slice pattern:
+
+#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+ panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+sourcepub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+starting at the end of the slice,
+and a remainder slice with length strictly less than N
.
Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
-Examples
-#![feature(slice_as_chunks)]
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
-
-let (chunks, remainder) = v.as_chunks_mut();
-remainder[0] = 9;
-for chunk in chunks {
- *chunk = [count; 2];
- count += 1;
-}
-assert_eq!(v, &[1, 1, 2, 2, 9]);
-sourcepub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])
🔬 This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
-starting at the end of the slice,
-and a remainder slice with length strictly less than N
.
+Examples
+#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+sourcepub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
🔬This is a nightly-only experimental API. (array_chunks
)
Returns an iterator over N
elements of the slice at a time, starting at the
+beginning of the slice.
+The chunks are array references and do not overlap. If N
does not divide the
+length of the slice, then the last up to N-1
elements will be omitted and can be
+retrieved from the remainder
function of the iterator.
+This method is the const generic equivalent of chunks_exact
.
Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
-Examples
-#![feature(slice_as_chunks)]
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
+Examples
+#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
sourcepub unsafe fn as_chunks_unchecked_mut<const N: usize>(
+ &mut self
+) -> &mut [[T; N]]
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+assuming that there’s no remainder.
+Safety
+This may only be called when
+
+- The slice splits exactly into
N
-element chunks (aka self.len() % N == 0
).
+N != 0
.
+
+Examples
+#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+ // SAFETY: 1-element chunks never have remainder
+ unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+ // SAFETY: The slice length (6) is a multiple of 3
+ unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
-let (remainder, chunks) = v.as_rchunks_mut();
-remainder[0] = 9;
-for chunk in chunks {
- *chunk = [count; 2];
- count += 1;
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+sourcepub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+starting at the beginning of the slice,
+and a remainder slice with length strictly less than N
.
+Panics
+Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
+Examples
+#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+ *chunk = [count; 2];
+ count += 1;
}
-assert_eq!(v, &[9, 1, 1, 2, 2]);
-sourcepub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>
🔬 This is a nightly-only experimental API. (array_chunks
)
Returns an iterator over N
elements of the slice at a time, starting at the
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+sourcepub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
Splits the slice into a slice of N
-element arrays,
+starting at the end of the slice,
+and a remainder slice with length strictly less than N
.
+Panics
+Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
+Examples
+#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+ *chunk = [count; 2];
+ count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+sourcepub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>
🔬This is a nightly-only experimental API. (array_chunks
)
Returns an iterator over N
elements of the slice at a time, starting at the
beginning of the slice.
The chunks are mutable array references and do not overlap. If N
does not divide
the length of the slice, then the last up to N-1
elements will be omitted and
can be retrieved from the into_remainder
function of the iterator.
-This method is the const generic equivalent of chunks_exact_mut
.
-Panics
+This method is the const generic equivalent of chunks_exact_mut
.
+Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
-Examples
-#![feature(array_chunks)]
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
+Examples
+#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
-for chunk in v.array_chunks_mut() {
- *chunk = [count; 2];
- count += 1;
+for chunk in v.array_chunks_mut() {
+ *chunk = [count; 2];
+ count += 1;
}
-assert_eq!(v, &[1, 1, 2, 2, 0]);
-
sourcepub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
🔬 This is a nightly-only experimental API. (array_windows
)
Returns an iterator over overlapping windows of N
elements of a slice,
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+sourcepub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
🔬This is a nightly-only experimental API. (array_windows
)
Returns an iterator over overlapping windows of N
elements of a slice,
starting at the beginning of the slice.
-This is the const generic equivalent of windows
.
+This is the const generic equivalent of windows
.
If N
is greater than the size of the slice, it will return no windows.
-Panics
+Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
-Examples
-#![feature(array_windows)]
-let slice = [0, 1, 2, 3];
-let mut iter = slice.array_windows();
-assert_eq!(iter.next().unwrap(), &[0, 1]);
-assert_eq!(iter.next().unwrap(), &[1, 2]);
-assert_eq!(iter.next().unwrap(), &[2, 3]);
-assert!(iter.next().is_none());
-1.31.0 · sourcepub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+
Examples
+#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+1.31.0 · sourcepub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last chunk will not have length chunk_size
.
-See rchunks_exact
for a variant of this iterator that returns chunks of always exactly
-chunk_size
elements, and chunks
for the same iterator but starting at the beginning
+
See rchunks_exact
for a variant of this iterator that returns chunks of always exactly
+chunk_size
elements, and chunks
for the same iterator but starting at the beginning
of the slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let mut iter = slice.rchunks(2);
-assert_eq!(iter.next().unwrap(), &['e', 'm']);
-assert_eq!(iter.next().unwrap(), &['o', 'r']);
-assert_eq!(iter.next().unwrap(), &['l']);
-assert!(iter.next().is_none());
-1.31.0 · sourcepub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+
Examples
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+1.31.0 · sourcepub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
length of the slice, then the last chunk will not have length chunk_size
.
-See rchunks_exact_mut
for a variant of this iterator that returns chunks of always
-exactly chunk_size
elements, and chunks_mut
for the same iterator but starting at the
+
See rchunks_exact_mut
for a variant of this iterator that returns chunks of always
+exactly chunk_size
elements, and chunks_mut
for the same iterator but starting at the
beginning of the slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
+Examples
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
-for chunk in v.rchunks_mut(2) {
- for elem in chunk.iter_mut() {
- *elem += count;
+for chunk in v.rchunks_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
}
- count += 1;
+ count += 1;
}
-assert_eq!(v, &[3, 2, 2, 1, 1]);
-
1.31.0 · sourcepub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+1.31.0 · sourcepub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
end of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
-resulting code better than in the case of rchunks
.
-See rchunks
for a variant of this iterator that also returns the remainder as a smaller
-chunk, and chunks_exact
for the same iterator but starting at the beginning of the
+resulting code better than in the case of rchunks
.
+See rchunks
for a variant of this iterator that also returns the remainder as a smaller
+chunk, and chunks_exact
for the same iterator but starting at the beginning of the
slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let slice = ['l', 'o', 'r', 'e', 'm'];
-let mut iter = slice.rchunks_exact(2);
-assert_eq!(iter.next().unwrap(), &['e', 'm']);
-assert_eq!(iter.next().unwrap(), &['o', 'r']);
-assert!(iter.next().is_none());
-assert_eq!(iter.remainder(), &['l']);
-1.31.0 · sourcepub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+
Examples
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+1.31.0 · sourcepub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
length of the slice, then the last up to chunk_size-1
elements will be omitted and can be
retrieved from the into_remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
-resulting code better than in the case of chunks_mut
.
-See rchunks_mut
for a variant of this iterator that also returns the remainder as a
-smaller chunk, and chunks_exact_mut
for the same iterator but starting at the beginning
+resulting code better than in the case of chunks_mut
.
+See rchunks_mut
for a variant of this iterator that also returns the remainder as a
+smaller chunk, and chunks_exact_mut
for the same iterator but starting at the beginning
of the slice.
-Panics
+Panics
Panics if chunk_size
is 0.
-Examples
-let v = &mut [0, 0, 0, 0, 0];
-let mut count = 1;
+Examples
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
-for chunk in v.rchunks_exact_mut(2) {
- for elem in chunk.iter_mut() {
- *elem += count;
+for chunk in v.rchunks_exact_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
}
- count += 1;
+ count += 1;
}
-assert_eq!(v, &[0, 2, 2, 1, 1]);
-
sourcepub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where
+ F: FnMut(&T, &T) -> bool,
🔬This is a nightly-only experimental API. (slice_group_by
)
Returns an iterator over the slice producing non-overlapping runs
of elements using the predicate to separate them.
The predicate is called on two elements following themselves,
it means the predicate is called on slice[0]
and slice[1]
then on slice[1]
and slice[2]
and so on.
-Examples
-#![feature(slice_group_by)]
+Examples
+#![feature(slice_group_by)]
-let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
-let mut iter = slice.group_by(|a, b| a == b);
+let mut iter = slice.group_by(|a, b| a == b);
-assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
-assert_eq!(iter.next(), Some(&[3, 3][..]));
-assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
-assert_eq!(iter.next(), None);
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
-#![feature(slice_group_by)]
+#![feature(slice_group_by)]
-let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
-let mut iter = slice.group_by(|a, b| a <= b);
+let mut iter = slice.group_by(|a, b| a <= b);
-assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
-assert_eq!(iter.next(), Some(&[2, 3][..]));
-assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
-assert_eq!(iter.next(), None);
-
sourcepub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F> where
F: FnMut(&T, &T) -> bool,
🔬 This is a nightly-only experimental API. (slice_group_by
)
Returns an iterator over the slice producing non-overlapping mutable
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+sourcepub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>where
+ F: FnMut(&T, &T) -> bool,
🔬This is a nightly-only experimental API. (slice_group_by
)
Returns an iterator over the slice producing non-overlapping mutable
runs of elements using the predicate to separate them.
The predicate is called on two elements following themselves,
it means the predicate is called on slice[0]
and slice[1]
then on slice[1]
and slice[2]
and so on.
-Examples
-#![feature(slice_group_by)]
+Examples
+#![feature(slice_group_by)]
-let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
-let mut iter = slice.group_by_mut(|a, b| a == b);
+let mut iter = slice.group_by_mut(|a, b| a == b);
-assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
-assert_eq!(iter.next(), Some(&mut [3, 3][..]));
-assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
-assert_eq!(iter.next(), None);
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
-#![feature(slice_group_by)]
+#![feature(slice_group_by)]
-let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
-let mut iter = slice.group_by_mut(|a, b| a <= b);
+let mut iter = slice.group_by_mut(|a, b| a <= b);
-assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
-assert_eq!(iter.next(), Some(&mut [2, 3][..]));
-assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
-assert_eq!(iter.next(), None);
-
1.0.0 · sourcepub fn split_at(&self, mid: usize) -> (&[T], &[T])
Divides one slice into two at an index.
The first will contain all indices from [0, mid)
(excluding
the index mid
itself) and the second will contain all
indices from [mid, len)
(excluding the index len
itself).
-Panics
+Panics
Panics if mid > len
.
-Examples
-let v = [1, 2, 3, 4, 5, 6];
+Examples
+let v = [1, 2, 3, 4, 5, 6];
{
- let (left, right) = v.split_at(0);
- assert_eq!(left, []);
- assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+ let (left, right) = v.split_at(0);
+ assert_eq!(left, []);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
{
- let (left, right) = v.split_at(2);
- assert_eq!(left, [1, 2]);
- assert_eq!(right, [3, 4, 5, 6]);
+ let (left, right) = v.split_at(2);
+ assert_eq!(left, [1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
}
{
- let (left, right) = v.split_at(6);
- assert_eq!(left, [1, 2, 3, 4, 5, 6]);
- assert_eq!(right, []);
+ let (left, right) = v.split_at(6);
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
}
-
1.0.0 · sourcepub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])
Divides one mutable slice into two at an index.
+1.0.0 · sourcepub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])
Divides one mutable slice into two at an index.
The first will contain all indices from [0, mid)
(excluding
the index mid
itself) and the second will contain all
indices from [mid, len)
(excluding the index len
itself).
-Panics
+Panics
Panics if mid > len
.
-Examples
-let mut v = [1, 0, 3, 0, 5, 6];
-let (left, right) = v.split_at_mut(2);
-assert_eq!(left, [1, 0]);
-assert_eq!(right, [3, 0, 5, 6]);
-left[1] = 2;
-right[1] = 4;
-assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-sourcepub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
🔬 This is a nightly-only experimental API. (slice_split_at_unchecked
)
Divides one slice into two at an index, without doing bounds checking.
+Examples
+let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+sourcepub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
🔬This is a nightly-only experimental API. (slice_split_at_unchecked
)
Divides one slice into two at an index, without doing bounds checking.
The first will contain all indices from [0, mid)
(excluding
the index mid
itself) and the second will contain all
indices from [mid, len)
(excluding the index len
itself).
-For a safe alternative see split_at
.
-Safety
-Calling this method with an out-of-bounds index is undefined behavior
-even if the resulting reference is not used. The caller has to ensure that
-0 <= mid <= self.len()
.
-Examples
-#![feature(slice_split_at_unchecked)]
-
-let v = [1, 2, 3, 4, 5, 6];
-
-unsafe {
- let (left, right) = v.split_at_unchecked(0);
- assert_eq!(left, []);
- assert_eq!(right, [1, 2, 3, 4, 5, 6]);
-}
-
-unsafe {
- let (left, right) = v.split_at_unchecked(2);
- assert_eq!(left, [1, 2]);
- assert_eq!(right, [3, 4, 5, 6]);
-}
-
-unsafe {
- let (left, right) = v.split_at_unchecked(6);
- assert_eq!(left, [1, 2, 3, 4, 5, 6]);
- assert_eq!(right, []);
-}
-sourcepub unsafe fn split_at_mut_unchecked(
&mut self,
mid: usize
) -> (&mut [T], &mut [T])
🔬 This is a nightly-only experimental API. (slice_split_at_unchecked
)
Divides one mutable slice into two at an index, without doing bounds checking.
-The first will contain all indices from [0, mid)
(excluding
-the index mid
itself) and the second will contain all
-indices from [mid, len)
(excluding the index len
itself).
-For a safe alternative see split_at_mut
.
+For a safe alternative see split_at
.
Safety
Calling this method with an out-of-bounds index is undefined behavior
even if the resulting reference is not used. The caller has to ensure that
0 <= mid <= self.len()
.
-Examples
-#![feature(slice_split_at_unchecked)]
+Examples
+#![feature(slice_split_at_unchecked)]
-let mut v = [1, 0, 3, 0, 5, 6];
-// scoped to restrict the lifetime of the borrows
-unsafe {
- let (left, right) = v.split_at_mut_unchecked(2);
- assert_eq!(left, [1, 0]);
- assert_eq!(right, [3, 0, 5, 6]);
- left[1] = 2;
- right[1] = 4;
-}
-assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-
sourcepub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])
🔬 This is a nightly-only experimental API. (split_array
)
Divides one slice into an array and a remainder slice at an index.
-The array will contain all indices from [0, N)
(excluding
-the index N
itself) and the slice will contain all
-indices from [N, len)
(excluding the index len
itself).
-Panics
-Panics if N > len
.
-Examples
-#![feature(split_array)]
+let v = [1, 2, 3, 4, 5, 6];
-let v = &[1, 2, 3, 4, 5, 6][..];
-
-{
- let (left, right) = v.split_array_ref::<0>();
- assert_eq!(left, &[]);
- assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+unsafe {
+ let (left, right) = v.split_at_unchecked(0);
+ assert_eq!(left, []);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
-{
- let (left, right) = v.split_array_ref::<2>();
- assert_eq!(left, &[1, 2]);
- assert_eq!(right, [3, 4, 5, 6]);
+unsafe {
+ let (left, right) = v.split_at_unchecked(2);
+ assert_eq!(left, [1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
}
-{
- let (left, right) = v.split_array_ref::<6>();
- assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
- assert_eq!(right, []);
+unsafe {
+ let (left, right) = v.split_at_unchecked(6);
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
}
-sourcepub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])
🔬 This is a nightly-only experimental API. (split_array
)
Divides one mutable slice into an array and a remainder slice at an index.
+sourcepub unsafe fn split_at_mut_unchecked(
+ &mut self,
+ mid: usize
+) -> (&mut [T], &mut [T])
🔬This is a nightly-only experimental API. (slice_split_at_unchecked
)
Divides one mutable slice into two at an index, without doing bounds checking.
+The first will contain all indices from [0, mid)
(excluding
+the index mid
itself) and the second will contain all
+indices from [mid, len)
(excluding the index len
itself).
+For a safe alternative see split_at_mut
.
+Safety
+Calling this method with an out-of-bounds index is undefined behavior
+even if the resulting reference is not used. The caller has to ensure that
+0 <= mid <= self.len()
.
+Examples
+#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+ let (left, right) = v.split_at_mut_unchecked(2);
+ assert_eq!(left, [1, 0]);
+ assert_eq!(right, [3, 0, 5, 6]);
+ left[1] = 2;
+ right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+sourcepub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])
🔬This is a nightly-only experimental API. (split_array
)
Divides one slice into an array and a remainder slice at an index.
The array will contain all indices from [0, N)
(excluding
the index N
itself) and the slice will contain all
indices from [N, len)
(excluding the index len
itself).
-Panics
+Panics
Panics if N > len
.
-Examples
-#![feature(split_array)]
+Examples
+#![feature(split_array)]
-let mut v = &mut [1, 0, 3, 0, 5, 6][..];
-let (left, right) = v.split_array_mut::<2>();
-assert_eq!(left, &mut [1, 0]);
-assert_eq!(right, [3, 0, 5, 6]);
-left[1] = 2;
-right[1] = 4;
-assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-
sourcepub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])
🔬 This is a nightly-only experimental API. (split_array
)
Divides one slice into an array and a remainder slice at an index from
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+ let (left, right) = v.split_array_ref::<0>();
+ assert_eq!(left, &[]);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_array_ref::<2>();
+ assert_eq!(left, &[1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_array_ref::<6>();
+ assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
+}
+sourcepub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])
🔬This is a nightly-only experimental API. (split_array
)
Divides one mutable slice into an array and a remainder slice at an index.
+The array will contain all indices from [0, N)
(excluding
+the index N
itself) and the slice will contain all
+indices from [N, len)
(excluding the index len
itself).
+Panics
+Panics if N > len
.
+Examples
+#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+sourcepub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])
🔬This is a nightly-only experimental API. (split_array
)
Divides one slice into an array and a remainder slice at an index from
the end.
The slice will contain all indices from [0, len - N)
(excluding
the index len - N
itself) and the array will contain all
indices from [len - N, len)
(excluding the index len
itself).
-Panics
+Panics
Panics if N > len
.
-Examples
-#![feature(split_array)]
+Examples
+#![feature(split_array)]
-let v = &[1, 2, 3, 4, 5, 6][..];
+let v = &[1, 2, 3, 4, 5, 6][..];
{
- let (left, right) = v.rsplit_array_ref::<0>();
- assert_eq!(left, [1, 2, 3, 4, 5, 6]);
- assert_eq!(right, &[]);
+ let (left, right) = v.rsplit_array_ref::<0>();
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, &[]);
}
{
- let (left, right) = v.rsplit_array_ref::<2>();
- assert_eq!(left, [1, 2, 3, 4]);
- assert_eq!(right, &[5, 6]);
+ let (left, right) = v.rsplit_array_ref::<2>();
+ assert_eq!(left, [1, 2, 3, 4]);
+ assert_eq!(right, &[5, 6]);
}
{
- let (left, right) = v.rsplit_array_ref::<6>();
- assert_eq!(left, []);
- assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+ let (left, right) = v.rsplit_array_ref::<6>();
+ assert_eq!(left, []);
+ assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
}
-
sourcepub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])
🔬 This is a nightly-only experimental API. (split_array
)
Divides one mutable slice into an array and a remainder slice at an
+
sourcepub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])
🔬This is a nightly-only experimental API. (split_array
)
Divides one mutable slice into an array and a remainder slice at an
index from the end.
The slice will contain all indices from [0, len - N)
(excluding
the index N
itself) and the array will contain all
indices from [len - N, len)
(excluding the index len
itself).
-Panics
+Panics
Panics if N > len
.
-Examples
-#![feature(split_array)]
+Examples
+#![feature(split_array)]
-let mut v = &mut [1, 0, 3, 0, 5, 6][..];
-let (left, right) = v.rsplit_array_mut::<4>();
-assert_eq!(left, [1, 0]);
-assert_eq!(right, &mut [3, 0, 5, 6]);
-left[1] = 2;
-right[1] = 4;
-assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-
1.0.0 · sourcepub fn split<F>(&self, pred: F) -> Split<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+1.0.0 · sourcepub fn split<F>(&self, pred: F) -> Split<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
. The matched element is not contained in the subslices.
-Examples
-let slice = [10, 40, 33, 20];
-let mut iter = slice.split(|num| num % 3 == 0);
+Examples
+let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
-assert_eq!(iter.next().unwrap(), &[10, 40]);
-assert_eq!(iter.next().unwrap(), &[20]);
-assert!(iter.next().is_none());
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
If the first element is matched, an empty slice will be the first item
returned by the iterator. Similarly, if the last element in the slice
is matched, an empty slice will be the last item returned by the
iterator:
-let slice = [10, 40, 33];
-let mut iter = slice.split(|num| num % 3 == 0);
+let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
-assert_eq!(iter.next().unwrap(), &[10, 40]);
-assert_eq!(iter.next().unwrap(), &[]);
-assert!(iter.next().is_none());
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
If two matched elements are directly adjacent, an empty slice will be
present between them:
-let slice = [10, 6, 33, 20];
-let mut iter = slice.split(|num| num % 3 == 0);
+let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
-assert_eq!(iter.next().unwrap(), &[10]);
-assert_eq!(iter.next().unwrap(), &[]);
-assert_eq!(iter.next().unwrap(), &[20]);
-assert!(iter.next().is_none());
-
1.0.0 · sourcepub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+1.0.0 · sourcepub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
match pred
. The matched element is not contained in the subslices.
-Examples
-let mut v = [10, 40, 30, 20, 60, 50];
+Examples
+let mut v = [10, 40, 30, 20, 60, 50];
-for group in v.split_mut(|num| *num % 3 == 0) {
- group[0] = 1;
+for group in v.split_mut(|num| *num % 3 == 0) {
+ group[0] = 1;
}
-assert_eq!(v, [1, 40, 30, 1, 60, 1]);
-
1.51.0 · sourcepub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+1.51.0 · sourcepub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
. The matched element is contained in the end of the previous
subslice as a terminator.
-Examples
-let slice = [10, 40, 33, 20];
-let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+Examples
+let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
-assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
-assert_eq!(iter.next().unwrap(), &[20]);
-assert!(iter.next().is_none());
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
If the last element of the slice is matched,
that element will be considered the terminator of the preceding slice.
That slice will be the last item returned by the iterator.
-let slice = [3, 10, 40, 33];
-let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
-assert_eq!(iter.next().unwrap(), &[3]);
-assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
-assert!(iter.next().is_none());
-
1.51.0 · sourcepub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+1.51.0 · sourcepub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
match pred
. The matched element is contained in the previous
subslice as a terminator.
-Examples
-let mut v = [10, 40, 30, 20, 60, 50];
+Examples
+let mut v = [10, 40, 30, 20, 60, 50];
-for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
- let terminator_idx = group.len()-1;
- group[terminator_idx] = 1;
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+ let terminator_idx = group.len()-1;
+ group[terminator_idx] = 1;
}
-assert_eq!(v, [10, 40, 1, 20, 1, 1]);
-
1.27.0 · sourcepub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
, starting at the end of the slice and working backwards.
The matched element is not contained in the subslices.
-Examples
-let slice = [11, 22, 33, 0, 44, 55];
-let mut iter = slice.rsplit(|num| *num == 0);
+Examples
+let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
-assert_eq!(iter.next().unwrap(), &[44, 55]);
-assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
-assert_eq!(iter.next(), None);
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
As with split()
, if the first or last element is matched, an empty
slice will be the first (or last) item returned by the iterator.
-let v = &[0, 1, 1, 2, 3, 5, 8];
-let mut it = v.rsplit(|n| *n % 2 == 0);
-assert_eq!(it.next().unwrap(), &[]);
-assert_eq!(it.next().unwrap(), &[3, 5]);
-assert_eq!(it.next().unwrap(), &[1, 1]);
-assert_eq!(it.next().unwrap(), &[]);
-assert_eq!(it.next(), None);
-1.27.0 · sourcepub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
+
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+1.27.0 · sourcepub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that
match pred
, starting at the end of the slice and working
backwards. The matched element is not contained in the subslices.
-Examples
-let mut v = [100, 400, 300, 200, 600, 500];
+Examples
+let mut v = [100, 400, 300, 200, 600, 500];
-let mut count = 0;
-for group in v.rsplit_mut(|num| *num % 3 == 0) {
- count += 1;
- group[0] = count;
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+ count += 1;
+ group[0] = count;
}
-assert_eq!(v, [3, 400, 300, 2, 600, 1]);
-
1.0.0 · sourcepub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
, limited to returning at most n
items. The matched element is
not contained in the subslices.
The last element returned, if any, will contain the remainder of the
slice.
-Examples
+Examples
Print the slice split once by numbers divisible by 3 (i.e., [10, 40]
,
[20, 60, 50]
):
-let v = [10, 40, 30, 20, 60, 50];
+let v = [10, 40, 30, 20, 60, 50];
-for group in v.splitn(2, |num| *num % 3 == 0) {
+for group in v.splitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
-
1.0.0 · sourcepub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
+
1.0.0 · sourcepub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over mutable subslices separated by elements that match
pred
, limited to returning at most n
items. The matched element is
not contained in the subslices.
The last element returned, if any, will contain the remainder of the
slice.
-Examples
-let mut v = [10, 40, 30, 20, 60, 50];
+Examples
+let mut v = [10, 40, 30, 20, 60, 50];
-for group in v.splitn_mut(2, |num| *num % 3 == 0) {
- group[0] = 1;
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+ group[0] = 1;
}
-assert_eq!(v, [1, 40, 30, 1, 60, 50]);
-
1.0.0 · sourcepub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
limited to returning at most n
items. This starts at the end of
the slice and works backwards. The matched element is not contained in
the subslices.
The last element returned, if any, will contain the remainder of the
slice.
-Examples
+Examples
Print the slice split once, starting from the end, by numbers divisible
by 3 (i.e., [50]
, [10, 40, 30, 20]
):
-let v = [10, 40, 30, 20, 60, 50];
+let v = [10, 40, 30, 20, 60, 50];
-for group in v.rsplitn(2, |num| *num % 3 == 0) {
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
-
1.0.0 · sourcepub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F> where
F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
+
1.0.0 · sourcepub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>where
+ F: FnMut(&T) -> bool,
Returns an iterator over subslices separated by elements that match
pred
limited to returning at most n
items. This starts at the end of
the slice and works backwards. The matched element is not contained in
the subslices.
The last element returned, if any, will contain the remainder of the
slice.
-Examples
-let mut s = [10, 40, 30, 20, 60, 50];
+Examples
+let mut s = [10, 40, 30, 20, 60, 50];
-for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
- group[0] = 1;
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+ group[0] = 1;
}
-assert_eq!(s, [1, 40, 30, 20, 60, 1]);
-
1.0.0 · sourcepub fn contains(&self, x: &T) -> boolwhere
+ T: PartialEq<T>,
Returns true
if the slice contains an element with the given value.
This operation is O(n).
-Note that if you have a sorted slice, binary_search
may be faster.
-Examples
-let v = [10, 40, 30];
-assert!(v.contains(&30));
-assert!(!v.contains(&50));
+Note that if you have a sorted slice, binary_search
may be faster.
+Examples
+let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
If you do not have a &T
, but some other value that you can compare
with one (for example, String
implements PartialEq<str>
), you can
use iter().any
:
-let v = [String::from("hello"), String::from("world")]; // slice of `String`
-assert!(v.iter().any(|e| e == "hello")); // search with `&str`
-assert!(!v.iter().any(|e| e == "hi"));
-1.0.0 · sourcepub fn starts_with(&self, needle: &[T]) -> bool where
T: PartialEq<T>,
Returns true
if needle
is a prefix of the slice.
-Examples
-let v = [10, 40, 30];
-assert!(v.starts_with(&[10]));
-assert!(v.starts_with(&[10, 40]));
-assert!(!v.starts_with(&[50]));
-assert!(!v.starts_with(&[10, 50]));
+let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+1.0.0 · sourcepub fn starts_with(&self, needle: &[T]) -> boolwhere
+ T: PartialEq<T>,
Returns true
if needle
is a prefix of the slice.
+Examples
+let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
Always returns true
if needle
is an empty slice:
-let v = &[10, 40, 30];
-assert!(v.starts_with(&[]));
-let v: &[u8] = &[];
-assert!(v.starts_with(&[]));
-1.0.0 · sourcepub fn ends_with(&self, needle: &[T]) -> bool where
T: PartialEq<T>,
Returns true
if needle
is a suffix of the slice.
-Examples
-let v = [10, 40, 30];
-assert!(v.ends_with(&[30]));
-assert!(v.ends_with(&[40, 30]));
-assert!(!v.ends_with(&[50]));
-assert!(!v.ends_with(&[50, 30]));
+let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+1.0.0 · sourcepub fn ends_with(&self, needle: &[T]) -> boolwhere
+ T: PartialEq<T>,
Returns true
if needle
is a suffix of the slice.
+Examples
+let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
Always returns true
if needle
is an empty slice:
-let v = &[10, 40, 30];
-assert!(v.ends_with(&[]));
-let v: &[u8] = &[];
-assert!(v.ends_with(&[]));
-1.51.0 · sourcepub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
Returns a subslice with the prefix removed.
+let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+1.51.0 · sourcepub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where
+ P: SlicePattern<Item = T> + ?Sized,
+ T: PartialEq<T>,
Returns a subslice with the prefix removed.
If the slice starts with prefix
, returns the subslice after the prefix, wrapped in Some
.
If prefix
is empty, simply returns the original slice.
If the slice does not start with prefix
, returns None
.
-Examples
-let v = &[10, 40, 30];
-assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
-assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
-assert_eq!(v.strip_prefix(&[50]), None);
-assert_eq!(v.strip_prefix(&[10, 50]), None);
+Examples
+let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
-let prefix : &str = "he";
-assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
- Some(b"llo".as_ref()));
-
1.51.0 · sourcepub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
Returns a subslice with the suffix removed.
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+ Some(b"llo".as_ref()));
+1.51.0 · sourcepub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where
+ P: SlicePattern<Item = T> + ?Sized,
+ T: PartialEq<T>,
Returns a subslice with the suffix removed.
If the slice ends with suffix
, returns the subslice before the suffix, wrapped in Some
.
If suffix
is empty, simply returns the original slice.
If the slice does not end with suffix
, returns None
.
-Examples
-let v = &[10, 40, 30];
-assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
-assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
-assert_eq!(v.strip_suffix(&[50]), None);
-assert_eq!(v.strip_suffix(&[50, 30]), None);
-1.0.0 · sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize> where
T: Ord,
Binary searches this slice for a given element.
-This behaves similary to contains
if this slice is sorted.
-If the value is found then Result::Ok
is returned, containing the
+
Examples
+let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+1.0.0 · sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize>where
+ T: Ord,
Binary searches this slice for a given element.
+If the slice is not sorted, the returned result is unspecified and
+meaningless.
+If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
-If the value is not found then Result::Err
is returned, containing
+If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
-See also binary_search_by
, binary_search_by_key
, and partition_point
.
-Examples
+See also binary_search_by
, binary_search_by_key
, and partition_point
.
+Examples
Looks up a series of four elements. The first is found, with a
uniquely determined position; the second and third are not
found; the fourth could match any position in [1, 4]
.
-let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-assert_eq!(s.binary_search(&13), Ok(9));
-assert_eq!(s.binary_search(&4), Err(7));
-assert_eq!(s.binary_search(&100), Err(13));
-let r = s.binary_search(&1);
-assert!(match r { Ok(1..=4) => true, _ => false, });
+assert_eq!(s.binary_search(&13), Ok(9));
+assert_eq!(s.binary_search(&4), Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+If you want to find that whole range of matching items, rather than
+an arbitrary matching one, that can be done using partition_point
:
+
+let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
If you want to insert an item to a sorted vector, while maintaining
-sort order, consider using partition_point
:
+sort order, consider using partition_point
:
-let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-let num = 42;
-let idx = s.partition_point(|&x| x < num);
-// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
-s.insert(idx, num);
-assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
-1.0.0 · sourcepub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize> where
F: FnMut(&'a T) -> Ordering,
Binary searches this slice with a comparator function.
-This behaves similarly to contains
if this slice is sorted.
-The comparator function should implement an order consistent
-with the sort order of the underlying slice, returning an
-order code that indicates whether its argument is Less
,
-Equal
or Greater
the desired target.
-If the value is found then Result::Ok
is returned, containing the
+
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+1.0.0 · sourcepub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where
+ F: FnMut(&'a T) -> Ordering,
Binary searches this slice with a comparator function.
+The comparator function should return an order code that indicates
+whether its argument is Less
, Equal
or Greater
the desired
+target.
+If the slice is not sorted or if the comparator function does not
+implement an order consistent with the sort order of the underlying
+slice, the returned result is unspecified and meaningless.
+If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
-If the value is not found then Result::Err
is returned, containing
+If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
-See also binary_search
, binary_search_by_key
, and partition_point
.
-Examples
+See also binary_search
, binary_search_by_key
, and partition_point
.
+Examples
Looks up a series of four elements. The first is found, with a
uniquely determined position; the second and third are not
found; the fourth could match any position in [1, 4]
.
-let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-let seek = 13;
-assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
-let seek = 4;
-assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
-let seek = 100;
-assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
-let seek = 1;
-let r = s.binary_search_by(|probe| probe.cmp(&seek));
-assert!(match r { Ok(1..=4) => true, _ => false, });
-
1.10.0 · sourcepub fn binary_search_by_key<'a, B, F>(
&'a self,
b: &B,
f: F
) -> Result<usize, usize> where
F: FnMut(&'a T) -> B,
B: Ord,
Binary searches this slice with a key extraction function.
-This behaves similarly to contains
if this slice is sorted.
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+1.10.0 · sourcepub fn binary_search_by_key<'a, B, F>(
+ &'a self,
+ b: &B,
+ f: F
+) -> Result<usize, usize>where
+ F: FnMut(&'a T) -> B,
+ B: Ord,
Binary searches this slice with a key extraction function.
Assumes that the slice is sorted by the key, for instance with
-sort_by_key
using the same key extraction function.
-If the value is found then Result::Ok
is returned, containing the
+sort_by_key
using the same key extraction function.
+If the slice is not sorted by the key, the returned result is
+unspecified and meaningless.
+If the value is found then Result::Ok
is returned, containing the
index of the matching element. If there are multiple matches, then any
one of the matches could be returned. The index is chosen
deterministically, but is subject to change in future versions of Rust.
-If the value is not found then Result::Err
is returned, containing
+If the value is not found then Result::Err
is returned, containing
the index where a matching element could be inserted while maintaining
sorted order.
-See also binary_search
, binary_search_by
, and partition_point
.
-Examples
+See also binary_search
, binary_search_by
, and partition_point
.
+Examples
Looks up a series of four elements in a slice of pairs sorted by
their second elements. The first is found, with a uniquely
determined position; the second and third are not found; the
fourth could match any position in [1, 4]
.
-let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
(1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
(1, 21), (2, 34), (4, 55)];
-assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
-assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
-assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
-let r = s.binary_search_by_key(&1, |&(a, b)| b);
-assert!(match r { Ok(1..=4) => true, _ => false, });
-
1.20.0 · sourcepub fn sort_unstable(&mut self) where
T: Ord,
Sorts the slice, but might not preserve the order of equal elements.
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+1.20.0 · sourcepub fn sort_unstable(&mut self)where
+ T: Ord,
Sorts the slice, but might not preserve the order of equal elements.
This sort is unstable (i.e., may reorder equal elements), in-place
(i.e., does not allocate), and O(n * log(n)) worst-case.
-Current implementation
-The current algorithm is based on pattern-defeating quicksort by Orson Peters,
-which combines the fast average case of randomized quicksort with the fast worst case of
-heapsort, while achieving linear time on slices with certain patterns. It uses some
-randomization to avoid degenerate cases, but with a fixed seed to always provide
-deterministic behavior.
-It is typically faster than stable sorting, except in a few special cases, e.g., when the
-slice consists of several concatenated sorted sequences.
-Examples
-let mut v = [-5, 4, 1, -3, 2];
-
-v.sort_unstable();
-assert!(v == [-5, -3, 1, 2, 4]);
-1.20.0 · sourcepub fn sort_unstable_by<F>(&mut self, compare: F) where
F: FnMut(&T, &T) -> Ordering,
Sorts the slice with a comparator function, but might not preserve the order of equal
-elements.
-This sort is unstable (i.e., may reorder equal elements), in-place
-(i.e., does not allocate), and O(n * log(n)) worst-case.
-The comparator function must define a total ordering for the elements in the slice. If
-the ordering is not total, the order of the elements is unspecified. An order is a
-total order if it is (for all a
, b
and c
):
-
-- total and antisymmetric: exactly one of
a < b
, a == b
or a > b
is true, and
-- transitive,
a < b
and b < c
implies a < c
. The same must hold for both ==
and >
.
-
-For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
-partial_cmp
as our sort function when we know the slice doesn’t contain a NaN
.
-
-let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
-floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
-assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
Current implementation
The current algorithm is based on pattern-defeating quicksort by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
@@ -1262,127 +1503,186 @@ randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.
It is typically faster than stable sorting, except in a few special cases, e.g., when the
slice consists of several concatenated sorted sequences.
-Examples
-let mut v = [5, 4, 1, 3, 2];
-v.sort_unstable_by(|a, b| a.cmp(b));
-assert!(v == [1, 2, 3, 4, 5]);
+Examples
+let mut v = [-5, 4, 1, -3, 2];
-// reverse sorting
-v.sort_unstable_by(|a, b| b.cmp(a));
-assert!(v == [5, 4, 3, 2, 1]);
-
1.20.0 · sourcepub fn sort_unstable_by_key<K, F>(&mut self, f: F) where
F: FnMut(&T) -> K,
K: Ord,
Sorts the slice with a key extraction function, but might not preserve the order of equal
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+1.20.0 · sourcepub fn sort_unstable_by<F>(&mut self, compare: F)where
+ F: FnMut(&T, &T) -> Ordering,
Sorts the slice with a comparator function, but might not preserve the order of equal
elements.
This sort is unstable (i.e., may reorder equal elements), in-place
-(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is
-O(m).
+(i.e., does not allocate), and O(n * log(n)) worst-case.
+The comparator function must define a total ordering for the elements in the slice. If
+the ordering is not total, the order of the elements is unspecified. An order is a
+total order if it is (for all a
, b
and c
):
+
+- total and antisymmetric: exactly one of
a < b
, a == b
or a > b
is true, and
+- transitive,
a < b
and b < c
implies a < c
. The same must hold for both ==
and >
.
+
+For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
+partial_cmp
as our sort function when we know the slice doesn’t contain a NaN
.
+
+let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
Current implementation
The current algorithm is based on pattern-defeating quicksort by Orson Peters,
which combines the fast average case of randomized quicksort with the fast worst case of
heapsort, while achieving linear time on slices with certain patterns. It uses some
randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.
+It is typically faster than stable sorting, except in a few special cases, e.g., when the
+slice consists of several concatenated sorted sequences.
+Examples
+let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+1.20.0 · sourcepub fn sort_unstable_by_key<K, F>(&mut self, f: F)where
+ F: FnMut(&T) -> K,
+ K: Ord,
Sorts the slice with a key extraction function, but might not preserve the order of equal
+elements.
+This sort is unstable (i.e., may reorder equal elements), in-place
+(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is
+O(m).
+Current implementation
+The current algorithm is based on pattern-defeating quicksort by Orson Peters,
+which combines the fast average case of randomized quicksort with the fast worst case of
+heapsort, while achieving linear time on slices with certain patterns. It uses some
+randomization to avoid degenerate cases, but with a fixed seed to always provide
+deterministic behavior.
Due to its key calling strategy, sort_unstable_by_key
is likely to be slower than sort_by_cached_key
in
cases where the key function is expensive.
-Examples
-let mut v = [-5i32, 4, 1, -3, 2];
+Examples
+let mut v = [-5i32, 4, 1, -3, 2];
-v.sort_unstable_by_key(|k| k.abs());
-assert!(v == [1, 2, -3, 4, -5]);
-
1.49.0 · sourcepub fn select_nth_unstable(
+ &mut self,
+ index: usize
+) -> (&mut [T], &mut T, &mut [T])where
+ T: Ord,
Reorder the slice such that the element at index
is at its final sorted position.
This reordering has the additional property that any value at position i < index
will be
less than or equal to any value at a position j > index
. Additionally, this reordering is
unstable (i.e. any number of equal elements may end up at position index
), in-place
-(i.e. does not allocate), and O(n) worst-case. This function is also/ known as “kth
-element” in other libraries. It returns a triplet of the following values: all elements less
-than the one at the given index, the value at the given index, and all elements greater than
-the one at the given index.
-Current implementation
-The current algorithm is based on the quickselect portion of the same quicksort algorithm
-used for sort_unstable
.
-Panics
+(i.e. does not allocate), and runs in O(n) time.
+This function is also known as “kth element” in other libraries.
+It returns a triplet of the following from the reordered slice:
+the subslice prior to index
, the element at index
, and the subslice after index
;
+accordingly, the values in those two subslices will respectively all be less-than-or-equal-to
+and greater-than-or-equal-to the value of the element at index
.
+Current implementation
+The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also
+the basis for sort_unstable
. The fallback algorithm is Median of Medians using Tukey’s Ninther for
+pivot selection, which guarantees linear runtime for all inputs.
+Panics
Panics when index >= len()
, meaning it always panics on empty slices.
-Examples
-let mut v = [-5i32, 4, 1, -3, 2];
+Examples
+let mut v = [-5i32, 4, 1, -3, 2];
-// Find the median
-v.select_nth_unstable(2);
+// Find the median
+v.select_nth_unstable(2);
-// We are only guaranteed the slice will be one of the following, based on the way we sort
-// about the specified index.
-assert!(v == [-3, -5, 1, 2, 4] ||
- v == [-5, -3, 1, 2, 4] ||
- v == [-3, -5, 1, 4, 2] ||
- v == [-5, -3, 1, 4, 2]);
-
1.49.0 · sourcepub fn select_nth_unstable_by<F>(
&mut self,
index: usize,
compare: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T, &T) -> Ordering,
Reorder the slice with a comparator function such that the element at index
is at its
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+ v == [-5, -3, 1, 2, 4] ||
+ v == [-3, -5, 1, 4, 2] ||
+ v == [-5, -3, 1, 4, 2]);
+1.49.0 · sourcepub fn select_nth_unstable_by<F>(
+ &mut self,
+ index: usize,
+ compare: F
+) -> (&mut [T], &mut T, &mut [T])where
+ F: FnMut(&T, &T) -> Ordering,
Reorder the slice with a comparator function such that the element at index
is at its
final sorted position.
This reordering has the additional property that any value at position i < index
will be
less than or equal to any value at a position j > index
using the comparator function.
Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
-position index
), in-place (i.e. does not allocate), and O(n) worst-case. This function
-is also known as “kth element” in other libraries. It returns a triplet of the following
-values: all elements less than the one at the given index, the value at the given index,
-and all elements greater than the one at the given index, using the provided comparator
-function.
-Current implementation
-The current algorithm is based on the quickselect portion of the same quicksort algorithm
-used for sort_unstable
.
-Panics
+position index
), in-place (i.e. does not allocate), and runs in O(n) time.
+This function is also known as “kth element” in other libraries.
+It returns a triplet of the following from
+the slice reordered according to the provided comparator function: the subslice prior to
+index
, the element at index
, and the subslice after index
; accordingly, the values in
+those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
+the value of the element at index
.
+Current implementation
+The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also
+the basis for sort_unstable
. The fallback algorithm is Median of Medians using Tukey’s Ninther for
+pivot selection, which guarantees linear runtime for all inputs.
+Panics
Panics when index >= len()
, meaning it always panics on empty slices.
-Examples
-let mut v = [-5i32, 4, 1, -3, 2];
+Examples
+let mut v = [-5i32, 4, 1, -3, 2];
-// Find the median as if the slice were sorted in descending order.
-v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
-// We are only guaranteed the slice will be one of the following, based on the way we sort
-// about the specified index.
-assert!(v == [2, 4, 1, -5, -3] ||
- v == [2, 4, 1, -3, -5] ||
- v == [4, 2, 1, -5, -3] ||
- v == [4, 2, 1, -3, -5]);
-
1.49.0 · sourcepub fn select_nth_unstable_by_key<K, F>(
&mut self,
index: usize,
f: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T) -> K,
K: Ord,
Reorder the slice with a key extraction function such that the element at index
is at its
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+ v == [2, 4, 1, -3, -5] ||
+ v == [4, 2, 1, -5, -3] ||
+ v == [4, 2, 1, -3, -5]);
+1.49.0 · sourcepub fn select_nth_unstable_by_key<K, F>(
+ &mut self,
+ index: usize,
+ f: F
+) -> (&mut [T], &mut T, &mut [T])where
+ F: FnMut(&T) -> K,
+ K: Ord,
Reorder the slice with a key extraction function such that the element at index
is at its
final sorted position.
This reordering has the additional property that any value at position i < index
will be
less than or equal to any value at a position j > index
using the key extraction function.
Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
-position index
), in-place (i.e. does not allocate), and O(n) worst-case. This function
-is also known as “kth element” in other libraries. It returns a triplet of the following
-values: all elements less than the one at the given index, the value at the given index, and
-all elements greater than the one at the given index, using the provided key extraction
-function.
-Current implementation
-The current algorithm is based on the quickselect portion of the same quicksort algorithm
-used for sort_unstable
.
-Panics
+position index
), in-place (i.e. does not allocate), and runs in O(n) time.
+This function is also known as “kth element” in other libraries.
+It returns a triplet of the following from
+the slice reordered according to the provided key extraction function: the subslice prior to
+index
, the element at index
, and the subslice after index
; accordingly, the values in
+those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
+the value of the element at index
.
+Current implementation
+The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also
+the basis for sort_unstable
. The fallback algorithm is Median of Medians using Tukey’s Ninther for
+pivot selection, which guarantees linear runtime for all inputs.
+Panics
Panics when index >= len()
, meaning it always panics on empty slices.
-Examples
-let mut v = [-5i32, 4, 1, -3, 2];
+Examples
+let mut v = [-5i32, 4, 1, -3, 2];
-// Return the median as if the array were sorted according to absolute value.
-v.select_nth_unstable_by_key(2, |a| a.abs());
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
-// We are only guaranteed the slice will be one of the following, based on the way we sort
-// about the specified index.
-assert!(v == [1, 2, -3, 4, -5] ||
- v == [1, 2, -3, -5, 4] ||
- v == [2, 1, -3, 4, -5] ||
- v == [2, 1, -3, -5, 4]);
-
sourcepub fn partition_dedup(&mut self) -> (&mut [T], &mut [T]) where
T: PartialEq<T>,
🔬 This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all consecutive repeated elements to the end of the slice according to the
-PartialEq
trait implementation.
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+ v == [1, 2, -3, -5, 4] ||
+ v == [2, 1, -3, 4, -5] ||
+ v == [2, 1, -3, -5, 4]);
+sourcepub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])where
+ T: PartialEq<T>,
🔬This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all consecutive repeated elements to the end of the slice according to the
+PartialEq
trait implementation.
Returns two slices. The first contains no consecutive repeated elements.
The second contains all the duplicates in no specified order.
If the slice is sorted, the first returned slice contains no duplicates.
-Examples
-#![feature(slice_partition_dedup)]
+Examples
+#![feature(slice_partition_dedup)]
-let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
-let (dedup, duplicates) = slice.partition_dedup();
+let (dedup, duplicates) = slice.partition_dedup();
-assert_eq!(dedup, [1, 2, 3, 2, 1]);
-assert_eq!(duplicates, [2, 3, 1]);
-
sourcepub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T, &mut T) -> bool,
🔬 This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all but the first of consecutive elements to the end of the slice satisfying
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+sourcepub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])where
+ F: FnMut(&mut T, &mut T) -> bool,
🔬This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all but the first of consecutive elements to the end of the slice satisfying
a given equality relation.
Returns two slices. The first contains no consecutive repeated elements.
The second contains all the duplicates in no specified order.
@@ -1391,249 +1691,262 @@ must determine if the elements compare equal. The elements are passed in opposit
from their order in the slice, so if same_bucket(a, b)
returns true
, a
is moved
at the end of the slice.
If the slice is sorted, the first returned slice contains no duplicates.
-Examples
-#![feature(slice_partition_dedup)]
+Examples
+#![feature(slice_partition_dedup)]
-let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
-let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
-assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
-assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
-
sourcepub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T) -> K,
K: PartialEq<K>,
🔬 This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all but the first of consecutive elements to the end of the slice that resolve
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+sourcepub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])where
+ F: FnMut(&mut T) -> K,
+ K: PartialEq<K>,
🔬This is a nightly-only experimental API. (slice_partition_dedup
)
Moves all but the first of consecutive elements to the end of the slice that resolve
to the same key.
Returns two slices. The first contains no consecutive repeated elements.
The second contains all the duplicates in no specified order.
If the slice is sorted, the first returned slice contains no duplicates.
-Examples
-#![feature(slice_partition_dedup)]
+Examples
+#![feature(slice_partition_dedup)]
-let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
-let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
-assert_eq!(dedup, [10, 20, 30, 20, 11]);
-assert_eq!(duplicates, [21, 30, 13]);
-
1.26.0 · sourcepub fn rotate_left(&mut self, mid: usize)
Rotates the slice in-place such that the first mid
elements of the
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+1.26.0 · sourcepub fn rotate_left(&mut self, mid: usize)
Rotates the slice in-place such that the first mid
elements of the
slice move to the end while the last self.len() - mid
elements move to
the front. After calling rotate_left
, the element previously at index
mid
will become the first element in the slice.
-Panics
+Panics
This function will panic if mid
is greater than the length of the
slice. Note that mid == self.len()
does not panic and is a no-op
rotation.
Complexity
Takes linear (in self.len()
) time.
-Examples
-let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
-a.rotate_left(2);
-assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+Examples
+let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
Rotating a subslice:
-let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
-a[1..5].rotate_left(1);
-assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
-1.26.0 · sourcepub fn rotate_right(&mut self, k: usize)
Rotates the slice in-place such that the first self.len() - k
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+1.26.0 · sourcepub fn rotate_right(&mut self, k: usize)
Rotates the slice in-place such that the first self.len() - k
elements of the slice move to the end while the last k
elements move
to the front. After calling rotate_right
, the element previously at
index self.len() - k
will become the first element in the slice.
-Panics
+Panics
This function will panic if k
is greater than the length of the
slice. Note that k == self.len()
does not panic and is a no-op
rotation.
Complexity
Takes linear (in self.len()
) time.
-Examples
-let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
-a.rotate_right(2);
-assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
-Rotate a subslice:
+Examples
+let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+Rotating a subslice:
-let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
-a[1..5].rotate_right(1);
-assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
-1.50.0 · sourcepub fn fill(&mut self, value: T) where
T: Clone,
Fills self
with elements by cloning value
.
-Examples
-let mut buf = vec![0; 10];
-buf.fill(1);
-assert_eq!(buf, vec![1; 10]);
-1.51.0 · sourcepub fn fill_with<F>(&mut self, f: F) where
F: FnMut() -> T,
Fills self
with elements returned by calling a closure repeatedly.
+let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+1.50.0 · sourcepub fn fill(&mut self, value: T)where
+ T: Clone,
Fills self
with elements by cloning value
.
+Examples
+let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+1.51.0 · sourcepub fn fill_with<F>(&mut self, f: F)where
+ F: FnMut() -> T,
Fills self
with elements returned by calling a closure repeatedly.
This method uses a closure to create new values. If you’d rather
-Clone
a given value, use fill
. If you want to use the Default
-trait to generate values, you can pass Default::default
as the
+Clone
a given value, use fill
. If you want to use the Default
+trait to generate values, you can pass Default::default
as the
argument.
-Examples
-let mut buf = vec![1; 10];
-buf.fill_with(Default::default);
-assert_eq!(buf, vec![0; 10]);
-1.7.0 · sourcepub fn clone_from_slice(&mut self, src: &[T]) where
T: Clone,
Copies the elements from src
into self
.
+Examples
+let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+1.7.0 · sourcepub fn clone_from_slice(&mut self, src: &[T])where
+ T: Clone,
Copies the elements from src
into self
.
The length of src
must be the same as self
.
-Panics
+Panics
This function will panic if the two slices have different lengths.
-Examples
+Examples
Cloning two elements from a slice into another:
-let src = [1, 2, 3, 4];
-let mut dst = [0, 0];
+let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
-// Because the slices have to be the same length,
-// we slice the source slice from four elements
-// to two. It will panic if we don't do this.
-dst.clone_from_slice(&src[2..]);
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
-assert_eq!(src, [1, 2, 3, 4]);
-assert_eq!(dst, [3, 4]);
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
Rust enforces that there can only be one mutable reference with no
immutable references to a particular piece of data in a particular
scope. Because of this, attempting to use clone_from_slice
on a
single slice will result in a compile failure:
-ⓘlet mut slice = [1, 2, 3, 4, 5];
+ⓘlet mut slice = [1, 2, 3, 4, 5];
-slice[..2].clone_from_slice(&slice[3..]); // compile fail!
-To work around this, we can use split_at_mut
to create two distinct
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+To work around this, we can use split_at_mut
to create two distinct
sub-slices from a slice:
-let mut slice = [1, 2, 3, 4, 5];
+let mut slice = [1, 2, 3, 4, 5];
{
- let (left, right) = slice.split_at_mut(2);
- left.clone_from_slice(&right[1..]);
+ let (left, right) = slice.split_at_mut(2);
+ left.clone_from_slice(&right[1..]);
}
-assert_eq!(slice, [4, 5, 3, 4, 5]);
-
1.9.0 · sourcepub fn copy_from_slice(&mut self, src: &[T]) where
T: Copy,
Copies all elements from src
into self
, using a memcpy.
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+1.9.0 · sourcepub fn copy_from_slice(&mut self, src: &[T])where
+ T: Copy,
Copies all elements from src
into self
, using a memcpy.
The length of src
must be the same as self
.
-If T
does not implement Copy
, use clone_from_slice
.
-Panics
+If T
does not implement Copy
, use clone_from_slice
.
+Panics
This function will panic if the two slices have different lengths.
-Examples
+Examples
Copying two elements from a slice into another:
-let src = [1, 2, 3, 4];
-let mut dst = [0, 0];
+let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
-// Because the slices have to be the same length,
-// we slice the source slice from four elements
-// to two. It will panic if we don't do this.
-dst.copy_from_slice(&src[2..]);
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
-assert_eq!(src, [1, 2, 3, 4]);
-assert_eq!(dst, [3, 4]);
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
Rust enforces that there can only be one mutable reference with no
immutable references to a particular piece of data in a particular
scope. Because of this, attempting to use copy_from_slice
on a
single slice will result in a compile failure:
-ⓘlet mut slice = [1, 2, 3, 4, 5];
+ⓘlet mut slice = [1, 2, 3, 4, 5];
-slice[..2].copy_from_slice(&slice[3..]); // compile fail!
-To work around this, we can use split_at_mut
to create two distinct
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+To work around this, we can use split_at_mut
to create two distinct
sub-slices from a slice:
-let mut slice = [1, 2, 3, 4, 5];
+let mut slice = [1, 2, 3, 4, 5];
{
- let (left, right) = slice.split_at_mut(2);
- left.copy_from_slice(&right[1..]);
+ let (left, right) = slice.split_at_mut(2);
+ left.copy_from_slice(&right[1..]);
}
-assert_eq!(slice, [4, 5, 3, 4, 5]);
-
1.37.0 · sourcepub fn copy_within<R>(&mut self, src: R, dest: usize) where
R: RangeBounds<usize>,
T: Copy,
Copies elements from one part of the slice to another part of itself,
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+1.37.0 · sourcepub fn copy_within<R>(&mut self, src: R, dest: usize)where
+ R: RangeBounds<usize>,
+ T: Copy,
Copies elements from one part of the slice to another part of itself,
using a memmove.
src
is the range within self
to copy from. dest
is the starting
index of the range within self
to copy to, which will have the same
length as src
. The two ranges may overlap. The ends of the two ranges
must be less than or equal to self.len()
.
-Panics
+Panics
This function will panic if either range exceeds the end of the slice,
or if the end of src
is before the start.
-Examples
+Examples
Copying four bytes within a slice:
-let mut bytes = *b"Hello, World!";
+let mut bytes = *b"Hello, World!";
-bytes.copy_within(1..5, 8);
+bytes.copy_within(1..5, 8);
-assert_eq!(&bytes, b"Hello, Wello!");
-
1.27.0 · sourcepub fn swap_with_slice(&mut self, other: &mut [T])
Swaps all elements in self
with those in other
.
+assert_eq!(&bytes, b"Hello, Wello!");
+1.27.0 · sourcepub fn swap_with_slice(&mut self, other: &mut [T])
Swaps all elements in self
with those in other
.
The length of other
must be the same as self
.
-Panics
+Panics
This function will panic if the two slices have different lengths.
Example
Swapping two elements across slices:
-let mut slice1 = [0, 0];
-let mut slice2 = [1, 2, 3, 4];
+let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
-slice1.swap_with_slice(&mut slice2[2..]);
+slice1.swap_with_slice(&mut slice2[2..]);
-assert_eq!(slice1, [3, 4]);
-assert_eq!(slice2, [1, 2, 0, 0]);
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
Rust enforces that there can only be one mutable reference to a
particular piece of data in a particular scope. Because of this,
attempting to use swap_with_slice
on a single slice will result in
a compile failure:
-ⓘlet mut slice = [1, 2, 3, 4, 5];
-slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
-To work around this, we can use split_at_mut
to create two distinct
+
ⓘlet mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+To work around this, we can use split_at_mut
to create two distinct
mutable sub-slices from a slice:
-let mut slice = [1, 2, 3, 4, 5];
+let mut slice = [1, 2, 3, 4, 5];
{
- let (left, right) = slice.split_at_mut(2);
- left.swap_with_slice(&mut right[1..]);
+ let (left, right) = slice.split_at_mut(2);
+ left.swap_with_slice(&mut right[1..]);
}
-assert_eq!(slice, [4, 5, 3, 1, 2]);
-
1.30.0 · sourcepub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])
Transmute the slice to a slice of another type, ensuring alignment of the types is
maintained.
This method splits the slice into three distinct slices: prefix, correctly aligned middle
-slice of a new type, and the suffix slice. The method may make the middle slice the greatest
-length possible for a given type and input slice, but only your algorithm’s performance
-should depend on that, not its correctness. It is permissible for all of the input data to
-be returned as the prefix or suffix slice.
-This method has no purpose when either input element T
or output element U
are
-zero-sized and will return the original slice without splitting anything.
-Safety
-This method is essentially a transmute
with respect to the elements in the returned
-middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
-Examples
-Basic usage:
-
-unsafe {
- let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
- let (prefix, shorts, suffix) = bytes.align_to::<u16>();
- // less_efficient_algorithm_for_bytes(prefix);
- // more_efficient_algorithm_for_aligned_shorts(shorts);
- // less_efficient_algorithm_for_bytes(suffix);
-}
-1.30.0 · sourcepub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])
Transmute the slice to a slice of another type, ensuring alignment of the types is
-maintained.
-This method splits the slice into three distinct slices: prefix, correctly aligned middle
-slice of a new type, and the suffix slice. The method may make the middle slice the greatest
-length possible for a given type and input slice, but only your algorithm’s performance
-should depend on that, not its correctness. It is permissible for all of the input data to
-be returned as the prefix or suffix slice.
+slice of a new type, and the suffix slice. How exactly the slice is split up is not
+specified; the middle part may be smaller than necessary. However, if this fails to return a
+maximal middle part, that is because code is running in a context where performance does not
+matter, such as a sanitizer attempting to find alignment bugs. Regular code running
+in a default (debug or release) execution will return a maximal middle part.
This method has no purpose when either input element T
or output element U
are
zero-sized and will return the original slice without splitting anything.
Safety
This method is essentially a transmute
with respect to the elements in the returned
middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
-Examples
+Examples
Basic usage:
-unsafe {
- let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
- let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
- // less_efficient_algorithm_for_bytes(prefix);
- // more_efficient_algorithm_for_aligned_shorts(shorts);
- // less_efficient_algorithm_for_bytes(suffix);
-}
-sourcepub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T]) where
T: SimdElement,
Simd<T, LANES>: AsRef<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
🔬 This is a nightly-only experimental API. (portable_simd
)
Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
-This is a safe wrapper around slice::align_to
, so has the same weak
+
unsafe {
+ let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+ let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+ // less_efficient_algorithm_for_bytes(prefix);
+ // more_efficient_algorithm_for_aligned_shorts(shorts);
+ // less_efficient_algorithm_for_bytes(suffix);
+}
+1.30.0 · sourcepub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])
Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the
+types is maintained.
+This method splits the slice into three distinct slices: prefix, correctly aligned middle
+slice of a new type, and the suffix slice. How exactly the slice is split up is not
+specified; the middle part may be smaller than necessary. However, if this fails to return a
+maximal middle part, that is because code is running in a context where performance does not
+matter, such as a sanitizer attempting to find alignment bugs. Regular code running
+in a default (debug or release) execution will return a maximal middle part.
+This method has no purpose when either input element T
or output element U
are
+zero-sized and will return the original slice without splitting anything.
+Safety
+This method is essentially a transmute
with respect to the elements in the returned
+middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
+Examples
+Basic usage:
+
+unsafe {
+ let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+ let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+ // less_efficient_algorithm_for_bytes(prefix);
+ // more_efficient_algorithm_for_aligned_shorts(shorts);
+ // less_efficient_algorithm_for_bytes(suffix);
+}
+sourcepub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where
+ Simd<T, LANES>: AsRef<[T; LANES]>,
+ T: SimdElement,
+ LaneCount<LANES>: SupportedLaneCount,
🔬This is a nightly-only experimental API. (portable_simd
)
Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
+This is a safe wrapper around slice::align_to
, so has the same weak
postconditions as that method. You’re only assured that
self.len() == prefix.len() + middle.len() * LANES + suffix.len()
.
Notably, all of the following are possible:
@@ -1644,7 +1957,7 @@ postconditions as that method. You’re only assured that
That said, this is a safe method, so if you’re only writing safe code,
then this can at most cause incorrect logic, not unsoundness.
-Panics
+Panics
This will panic if the size of the SIMD type is different from
LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps
@@ -1652,36 +1965,42 @@ that from ever happening, as only power-of-two numbers of lanes are
supported. It’s possible that, in the future, those restrictions might
be lifted in a way that would make it possible to see panics from this
method for something like LANES == 3
.
-Examples
-#![feature(portable_simd)]
-use core::simd::SimdFloat;
+Examples
+#![feature(portable_simd)]
+use core::simd::SimdFloat;
-let short = &[1, 2, 3];
-let (prefix, middle, suffix) = short.as_simd::<4>();
-assert_eq!(middle, []); // Not enough elements for anything in the middle
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
-// They might be split in any possible way between prefix and suffix
-let it = prefix.iter().chain(suffix).copied();
-assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
-fn basic_simd_sum(x: &[f32]) -> f32 {
- use std::ops::Add;
- use std::simd::f32x4;
- let (prefix, middle, suffix) = x.as_simd();
- let sums = f32x4::from_array([
- prefix.iter().copied().sum(),
+fn basic_simd_sum(x: &[f32]) -> f32 {
+ use std::ops::Add;
+ use std::simd::f32x4;
+ let (prefix, middle, suffix) = x.as_simd();
+ let sums = f32x4::from_array([
+ prefix.iter().copied().sum(),
0.0,
0.0,
- suffix.iter().copied().sum(),
+ suffix.iter().copied().sum(),
]);
- let sums = middle.iter().copied().fold(sums, f32x4::add);
- sums.reduce_sum()
+ let sums = middle.iter().copied().fold(sums, f32x4::add);
+ sums.reduce_sum()
}
-let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
-assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
-
sourcepub fn as_simd_mut<const LANES: usize>(
&mut self
) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T]) where
T: SimdElement,
Simd<T, LANES>: AsMut<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
🔬 This is a nightly-only experimental API. (portable_simd
)
Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
-This is a safe wrapper around slice::align_to_mut
, so has the same weak
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+sourcepub fn as_simd_mut<const LANES: usize>(
+ &mut self
+) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])where
+ Simd<T, LANES>: AsMut<[T; LANES]>,
+ T: SimdElement,
+ LaneCount<LANES>: SupportedLaneCount,
🔬This is a nightly-only experimental API. (portable_simd
)
Split a mutable slice into a mutable prefix, a middle of aligned SIMD types,
+and a mutable suffix.
+This is a safe wrapper around slice::align_to_mut
, so has the same weak
postconditions as that method. You’re only assured that
self.len() == prefix.len() + middle.len() * LANES + suffix.len()
.
Notably, all of the following are possible:
@@ -1692,8 +2011,8 @@ postconditions as that method. You’re only assured that
That said, this is a safe method, so if you’re only writing safe code,
then this can at most cause incorrect logic, not unsoundness.
-This is the mutable version of slice::as_simd
; see that for examples.
-Panics
+This is the mutable version of slice::as_simd
; see that for examples.
+Panics
This will panic if the size of the SIMD type is different from
LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps
@@ -1701,234 +2020,231 @@ that from ever happening, as only power-of-two numbers of lanes are
supported. It’s possible that, in the future, those restrictions might
be lifted in a way that would make it possible to see panics from this
method for something like LANES == 3
.
-sourcepub fn is_sorted(&self) -> bool where
T: PartialOrd<T>,
🔬 This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted.
+sourcepub fn is_sorted(&self) -> boolwhere
+ T: PartialOrd<T>,
🔬This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted.
That is, for each element a
and its following element b
, a <= b
must hold. If the
slice yields exactly zero or one element, true
is returned.
Note that if Self::Item
is only PartialOrd
, but not Ord
, the above definition
implies that this function returns false
if any two consecutive items are not
comparable.
-Examples
-#![feature(is_sorted)]
-let empty: [i32; 0] = [];
+Examples
+#![feature(is_sorted)]
+let empty: [i32; 0] = [];
-assert!([1, 2, 2, 9].is_sorted());
-assert!(![1, 3, 2, 4].is_sorted());
-assert!([0].is_sorted());
-assert!(empty.is_sorted());
-assert!(![0.0, 1.0, f32::NAN].is_sorted());
-
sourcepub fn is_sorted_by<F>(&self, compare: F) -> bool where
F: FnMut(&T, &T) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted using the given comparator function.
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+sourcepub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere
+ F: FnMut(&'a T, &'a T) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted using the given comparator function.
Instead of using PartialOrd::partial_cmp
, this function uses the given compare
function to determine the ordering of two elements. Apart from that, it’s equivalent to
-is_sorted
; see its documentation for more information.
-sourcepub fn is_sorted_by_key<F, K>(&self, f: F) -> bool where
F: FnMut(&T) -> K,
K: PartialOrd<K>,
🔬 This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted using the given key extraction function.
+is_sorted
; see its documentation for more information.
+sourcepub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere
+ F: FnMut(&'a T) -> K,
+ K: PartialOrd<K>,
🔬This is a nightly-only experimental API. (is_sorted
)
Checks if the elements of this slice are sorted using the given key extraction function.
Instead of comparing the slice’s elements directly, this function compares the keys of the
-elements, as determined by f
. Apart from that, it’s equivalent to is_sorted
; see its
+elements, as determined by f
. Apart from that, it’s equivalent to is_sorted
; see its
documentation for more information.
-Examples
-#![feature(is_sorted)]
+Examples
+#![feature(is_sorted)]
-assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
-assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
-
1.52.0 · sourcepub fn partition_point<P>(&self, pred: P) -> usizewhere
+ P: FnMut(&T) -> bool,
Returns the index of the partition point according to the given predicate
(the index of the first element of the second partition).
The slice is assumed to be partitioned according to the given predicate.
This means that all elements for which the predicate returns true are at the start of the slice
and all elements for which the predicate returns false are at the end.
-For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
+For example, [7, 15, 3, 5, 4, 12, 6]
is partitioned under the predicate x % 2 != 0
(all odd numbers are at the start, all even at the end).
If this slice is not partitioned, the returned result is unspecified and meaningless,
as this method performs a kind of binary search.
-See also binary_search
, binary_search_by
, and binary_search_by_key
.
-Examples
-let v = [1, 2, 3, 3, 5, 6, 7];
-let i = v.partition_point(|&x| x < 5);
+See also binary_search
, binary_search_by
, and binary_search_by_key
.
+Examples
+let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
-assert_eq!(i, 4);
-assert!(v[..i].iter().all(|&x| x < 5));
-assert!(v[i..].iter().all(|&x| !(x < 5)));
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+If all elements of the slice match the predicate, including if the slice
+is empty, then the length of the slice will be returned:
+
+let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
If you want to insert an item to a sorted vector, while maintaining
sort order:
-let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-let num = 42;
-let idx = s.partition_point(|&x| x < num);
-s.insert(idx, num);
-assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
-sourcepub fn take<R>(self: &mut &'a [T], range: R) -> Option<&'a [T]> where
R: OneSidedRange<usize>,
🔬 This is a nightly-only experimental API. (slice_take
)
Removes the subslice corresponding to the given range
+
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+sourcepub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>where
+ R: OneSidedRange<usize>,
🔬This is a nightly-only experimental API. (slice_take
)
Removes the subslice corresponding to the given range
and returns a reference to it.
Returns None
and does not modify the slice if the given
range is out of bounds.
Note that this method only accepts one-sided ranges such as
2..
or ..6
, but not 2..6
.
-Examples
+Examples
Taking the first three elements of a slice:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &[_] = &['a', 'b', 'c', 'd'];
-let mut first_three = slice.take(..3).unwrap();
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
-assert_eq!(slice, &['d']);
-assert_eq!(first_three, &['a', 'b', 'c']);
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
Taking the last two elements of a slice:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &[_] = &['a', 'b', 'c', 'd'];
-let mut tail = slice.take(2..).unwrap();
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
-assert_eq!(slice, &['a', 'b']);
-assert_eq!(tail, &['c', 'd']);
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
Getting None
when range
is out of bounds:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
-assert_eq!(None, slice.take(5..));
-assert_eq!(None, slice.take(..5));
-assert_eq!(None, slice.take(..=4));
-let expected: &[char] = &['a', 'b', 'c', 'd'];
-assert_eq!(Some(expected), slice.take(..4));
-
sourcepub fn take_mut<R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]> where
R: OneSidedRange<usize>,
🔬 This is a nightly-only experimental API. (slice_take
)
Removes the subslice corresponding to the given range
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+sourcepub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>where
+ R: OneSidedRange<usize>,
🔬This is a nightly-only experimental API. (slice_take
)
Removes the subslice corresponding to the given range
and returns a mutable reference to it.
Returns None
and does not modify the slice if the given
range is out of bounds.
Note that this method only accepts one-sided ranges such as
2..
or ..6
, but not 2..6
.
-Examples
+Examples
Taking the first three elements of a slice:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
-let mut first_three = slice.take_mut(..3).unwrap();
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
-assert_eq!(slice, &mut ['d']);
-assert_eq!(first_three, &mut ['a', 'b', 'c']);
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
Taking the last two elements of a slice:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
-let mut tail = slice.take_mut(2..).unwrap();
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
-assert_eq!(slice, &mut ['a', 'b']);
-assert_eq!(tail, &mut ['c', 'd']);
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
Getting None
when range
is out of bounds:
-#![feature(slice_take)]
+#![feature(slice_take)]
-let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
-assert_eq!(None, slice.take_mut(5..));
-assert_eq!(None, slice.take_mut(..5));
-assert_eq!(None, slice.take_mut(..=4));
-let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
-assert_eq!(Some(expected), slice.take_mut(..4));
-
sourcepub fn take_first(self: &mut &'a [T]) -> Option<&'a T>
🔬 This is a nightly-only experimental API. (slice_take
)
Removes the first element of the slice and returns a reference
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+sourcepub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>
🔬This is a nightly-only experimental API. (slice_take
)
Removes the first element of the slice and returns a reference
to it.
Returns None
if the slice is empty.
-Examples
-#![feature(slice_take)]
+Examples
+#![feature(slice_take)]
-let mut slice: &[_] = &['a', 'b', 'c'];
-let first = slice.take_first().unwrap();
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
-assert_eq!(slice, &['b', 'c']);
-assert_eq!(first, &'a');
-
sourcepub fn take_first_mut(self: &mut &'a mut [T]) -> Option<&'a mut T>
🔬 This is a nightly-only experimental API. (slice_take
)
Removes the first element of the slice and returns a mutable
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+sourcepub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>
🔬This is a nightly-only experimental API. (slice_take
)
Removes the first element of the slice and returns a mutable
reference to it.
Returns None
if the slice is empty.
-Examples
-#![feature(slice_take)]
+Examples
+#![feature(slice_take)]
-let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
-let first = slice.take_first_mut().unwrap();
-*first = 'd';
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
-assert_eq!(slice, &['b', 'c']);
-assert_eq!(first, &'d');
-
sourcepub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>
🔬This is a nightly-only experimental API. (slice_take
)
Removes the last element of the slice and returns a reference
to it.
Returns None
if the slice is empty.
-Examples
-#![feature(slice_take)]
+Examples
+#![feature(slice_take)]
-let mut slice: &[_] = &['a', 'b', 'c'];
-let last = slice.take_last().unwrap();
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
-assert_eq!(slice, &['a', 'b']);
-assert_eq!(last, &'c');
-
sourcepub fn take_last_mut(self: &mut &'a mut [T]) -> Option<&'a mut T>
🔬 This is a nightly-only experimental API. (slice_take
)
Removes the last element of the slice and returns a mutable
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+sourcepub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>
🔬This is a nightly-only experimental API. (slice_take
)
Removes the last element of the slice and returns a mutable
reference to it.
Returns None
if the slice is empty.
-Examples
-#![feature(slice_take)]
+Examples
+#![feature(slice_take)]
-let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
-let last = slice.take_last_mut().unwrap();
-*last = 'd';
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
-assert_eq!(slice, &['a', 'b']);
-assert_eq!(last, &'d');
-
sourcepub fn sort_floats(&mut self)
🔬 This is a nightly-only experimental API. (sort_floats
)
Sorts the slice of floats.
-This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
-the ordering defined by f32::total_cmp
.
-Current implementation
-This uses the same sorting algorithm as sort_unstable_by
.
-Examples
-#![feature(sort_floats)]
-let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+sourcepub unsafe fn get_many_unchecked_mut<const N: usize>(
+ &mut self,
+ indices: [usize; N]
+) -> [&mut T; N]
🔬This is a nightly-only experimental API. (get_many_mut
)
Returns mutable references to many indices at once, without doing any checks.
+For a safe alternative see get_many_mut
.
+Safety
+Calling this method with overlapping or out-of-bounds indices is undefined behavior
+even if the resulting references are not used.
+Examples
+#![feature(get_many_mut)]
-v.sort_floats();
-let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
-assert_eq!(&v[..8], &sorted[..8]);
-assert!(v[8].is_nan());
-sourcepub fn flatten(&self) -> &[T]
🔬 This is a nightly-only experimental API. (slice_flatten
)
Takes a &[[T; N]]
, and flattens it to a &[T]
.
-Panics
-This panics if the length of the resulting slice would overflow a usize
.
-This is only possible when flattening a slice of arrays of zero-sized
-types, and thus tends to be irrelevant in practice. If
-size_of::<T>() > 0
, this will never panic.
-Examples
-#![feature(slice_flatten)]
+let x = &mut [1, 2, 4];
-assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
-
-assert_eq!(
- [[1, 2, 3], [4, 5, 6]].flatten(),
- [[1, 2], [3, 4], [5, 6]].flatten(),
-);
-
-let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
-assert!(slice_of_empty_arrays.flatten().is_empty());
-
-let empty_slice_of_arrays: &[[u32; 10]] = &[];
-assert!(empty_slice_of_arrays.flatten().is_empty());
-sourcepub fn flatten_mut(&mut self) -> &mut [T]
🔬 This is a nightly-only experimental API. (slice_flatten
)
Takes a &mut [[T; N]]
, and flattens it to a &mut [T]
.
-Panics
-This panics if the length of the resulting slice would overflow a usize
.
-This is only possible when flattening a slice of arrays of zero-sized
-types, and thus tends to be irrelevant in practice. If
-size_of::<T>() > 0
, this will never panic.
-Examples
-#![feature(slice_flatten)]
-
-fn add_5_to_all(slice: &mut [i32]) {
- for i in slice {
- *i += 5;
- }
+unsafe {
+ let [a, b] = x.get_many_unchecked_mut([0, 2]);
+ *a *= 10;
+ *b *= 100;
}
+assert_eq!(x, &[10, 2, 400]);
+sourcepub fn get_many_mut<const N: usize>(
+ &mut self,
+ indices: [usize; N]
+) -> Result<[&mut T; N], GetManyMutError<N>>
🔬This is a nightly-only experimental API. (get_many_mut
)
Returns mutable references to many indices at once.
+Returns an error if any index is out-of-bounds, or if the same index was
+passed more than once.
+Examples
+#![feature(get_many_mut)]
-let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
-add_5_to_all(array.flatten_mut());
-assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
-1.0.0 · sourcepub fn sort(&mut self)where
+ T: Ord,
Sorts the slice.
This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.
When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
-See sort_unstable
.
+See sort_unstable
.
Current implementation
The current algorithm is an adaptive, iterative merge sort inspired by
timsort.
@@ -1936,12 +2252,13 @@ It is designed to be very fast in cases where the slice is nearly sorted, or con
two or more sorted sequences concatenated one after another.
Also, it allocates temporary storage half the size of self
, but for short slices a
non-allocating insertion sort is used instead.
-Examples
-let mut v = [-5, 4, 1, -3, 2];
+Examples
+let mut v = [-5, 4, 1, -3, 2];
-v.sort();
-assert!(v == [-5, -3, 1, 2, 4]);
-
1.0.0 · sourcepub fn sort_by<F>(&mut self, compare: F)where
+ F: FnMut(&T, &T) -> Ordering,
Sorts the slice with a comparator function.
This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.
The comparator function must define a total ordering for the elements in the slice. If
the ordering is not total, the order of the elements is unspecified. An order is a
@@ -1950,15 +2267,15 @@ total order if it is (for all a
, b
and c
)
total and antisymmetric: exactly one of a < b
, a == b
or a > b
is true, and
transitive, a < b
and b < c
implies a < c
. The same must hold for both ==
and >
.
-For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
+
For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
partial_cmp
as our sort function when we know the slice doesn’t contain a NaN
.
-let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
-floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
-assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
-See sort_unstable_by
.
+See sort_unstable_by
.
Current implementation
The current algorithm is an adaptive, iterative merge sort inspired by
timsort.
@@ -1966,23 +2283,25 @@ It is designed to be very fast in cases where the slice is nearly sorted, or con
two or more sorted sequences concatenated one after another.
Also, it allocates temporary storage half the size of self
, but for short slices a
non-allocating insertion sort is used instead.
-Examples
-let mut v = [5, 4, 1, 3, 2];
-v.sort_by(|a, b| a.cmp(b));
-assert!(v == [1, 2, 3, 4, 5]);
+Examples
+let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
-// reverse sorting
-v.sort_by(|a, b| b.cmp(a));
-assert!(v == [5, 4, 3, 2, 1]);
-
1.7.0 · sourcepub fn sort_by_key<K, F>(&mut self, f: F) where
F: FnMut(&T) -> K,
K: Ord,
Sorts the slice with a key extraction function.
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+1.7.0 · sourcepub fn sort_by_key<K, F>(&mut self, f: F)where
+ F: FnMut(&T) -> K,
+ K: Ord,
Sorts the slice with a key extraction function.
This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n))
worst-case, where the key function is O(m).
For expensive key functions (e.g. functions that are not simple property accesses or
-basic operations), sort_by_cached_key
is likely to be
+basic operations), sort_by_cached_key
is likely to be
significantly faster, as it does not recompute element keys.
When applicable, unstable sorting is preferred because it is generally faster than stable
sorting and it doesn’t allocate auxiliary memory.
-See sort_unstable_by_key
.
+See sort_unstable_by_key
.
Current implementation
The current algorithm is an adaptive, iterative merge sort inspired by
timsort.
@@ -1990,12 +2309,14 @@ It is designed to be very fast in cases where the slice is nearly sorted, or con
two or more sorted sequences concatenated one after another.
Also, it allocates temporary storage half the size of self
, but for short slices a
non-allocating insertion sort is used instead.
-Examples
-let mut v = [-5i32, 4, 1, -3, 2];
+Examples
+let mut v = [-5i32, 4, 1, -3, 2];
-v.sort_by_key(|k| k.abs());
-assert!(v == [1, 2, -3, 4, -5]);
-
1.34.0 · sourcepub fn sort_by_cached_key<K, F>(&mut self, f: F) where
F: FnMut(&T) -> K,
K: Ord,
Sorts the slice with a key extraction function.
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+1.34.0 · sourcepub fn sort_by_cached_key<K, F>(&mut self, f: F)where
+ F: FnMut(&T) -> K,
+ K: Ord,
Sorts the slice with a key extraction function.
During sorting, the key function is called at most once per element, by using
temporary storage to remember the results of key evaluation.
The order of calls to the key function is unspecified and may change in future versions
@@ -2003,7 +2324,7 @@ of the standard library.
This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n))
worst-case, where the key function is O(m).
For simple key functions (e.g., functions that are property accesses or
-basic operations), sort_by_key
is likely to be
+basic operations), sort_by_key
is likely to be
faster.
Current implementation
The current algorithm is based on pattern-defeating quicksort by Orson Peters,
@@ -2013,73 +2334,83 @@ randomization to avoid degenerate cases, but with a fixed seed to always provide
deterministic behavior.
In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)>
the
length of the slice.
-Examples
-let mut v = [-5i32, 4, 32, -3, 2];
+Examples
+let mut v = [-5i32, 4, 32, -3, 2];
-v.sort_by_cached_key(|k| k.to_string());
-assert!(v == [-3, -5, 2, 32, 4]);
-
1.0.0 · sourcepub fn to_vec(&self) -> Vec<T, Global> where
T: Clone,
Copies self
into a new Vec
.
-Examples
-let s = [10, 40, 30];
-let x = s.to_vec();
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+1.0.0 · sourcepub fn to_vec(&self) -> Vec<T, Global>where
+ T: Clone,
Copies self
into a new Vec
.
+Examples
+let s = [10, 40, 30];
+let x = s.to_vec();
// Here, `s` and `x` can be modified independently.
-sourcepub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A> where
A: Allocator,
T: Clone,
🔬 This is a nightly-only experimental API. (allocator_api
)
Copies self
into a new Vec
with an allocator.
-Examples
-#![feature(allocator_api)]
+
sourcepub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where
+ A: Allocator,
+ T: Clone,
🔬This is a nightly-only experimental API. (allocator_api
)
Copies self
into a new Vec
with an allocator.
+Examples
+#![feature(allocator_api)]
-use std::alloc::System;
+use std::alloc::System;
-let s = [10, 40, 30];
-let x = s.to_vec_in(System);
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
// Here, `s` and `x` can be modified independently.
-1.40.0 · sourcepub fn repeat(&self, n: usize) -> Vec<T, Global> where
T: Copy,
Creates a vector by repeating a slice n
times.
+1.40.0 · sourcepub fn repeat(&self, n: usize) -> Vec<T, Global>where
+ T: Copy,
Creates a vector by copying a slice n
times.
Panics
This function will panic if the capacity would overflow.
-Examples
+Examples
Basic usage:
-assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
A panic upon overflow:
-ⓘ// this will panic at runtime
-b"0123456789abcdef".repeat(usize::MAX);
-1.0.0 · sourcepub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where
Item: ?Sized,
[T]: Concat<Item>,
Flattens a slice of T
into a single value Self::Output
.
-Examples
-assert_eq!(["hello", "world"].concat(), "helloworld");
-assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
-1.3.0 · sourcepub fn join<Separator>(&self, sep: Separator) -> <[T] as Join<Separator>>::Output where
[T]: Join<Separator>,
Flattens a slice of T
into a single value Self::Output
, placing a
+
ⓘ// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+1.0.0 · sourcepub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Outputwhere
+ [T]: Concat<Item>,
+ Item: ?Sized,
Flattens a slice of T
into a single value Self::Output
.
+Examples
+assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+1.3.0 · sourcepub fn join<Separator>(
+ &self,
+ sep: Separator
+) -> <[T] as Join<Separator>>::Outputwhere
+ [T]: Join<Separator>,
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
-Examples
-assert_eq!(["hello", "world"].join(" "), "hello world");
-assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
-assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
-1.0.0 · sourcepub fn connect<Separator>(
&self,
sep: Separator
) -> <[T] as Join<Separator>>::Output where
[T]: Join<Separator>,
👎 Deprecated since 1.3.0: renamed to join
-
Flattens a slice of T
into a single value Self::Output
, placing a
+
Examples
+assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+1.0.0 · sourcepub fn connect<Separator>(
+ &self,
+ sep: Separator
+) -> <[T] as Join<Separator>>::Outputwhere
+ [T]: Join<Separator>,
👎Deprecated since 1.3.0: renamed to join
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
-Examples
-assert_eq!(["hello", "world"].connect(" "), "hello world");
-assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
-1.23.0 · sourcepub fn to_ascii_uppercase(&self) -> Vec<u8, Global>
Returns a vector containing a copy of this slice where each byte
+
Examples
+assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+1.23.0 · sourcepub fn to_ascii_uppercase(&self) -> Vec<u8, Global>
Returns a vector containing a copy of this slice where each byte
is mapped to its ASCII upper case equivalent.
ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’,
but non-ASCII letters are unchanged.
-To uppercase the value in-place, use make_ascii_uppercase
.
-1.23.0 · sourcepub fn to_ascii_lowercase(&self) -> Vec<u8, Global>
Returns a vector containing a copy of this slice where each byte
+
To uppercase the value in-place, use make_ascii_uppercase
.
+1.23.0 · sourcepub fn to_ascii_lowercase(&self) -> Vec<u8, Global>
Returns a vector containing a copy of this slice where each byte
is mapped to its ASCII lower case equivalent.
ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’,
but non-ASCII letters are unchanged.
-To lowercase the value in-place, use make_ascii_lowercase
.
-Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for APP_NAMES
impl Send for APP_NAMES
impl Sync for APP_NAMES
impl Unpin for APP_NAMES
impl UnwindSafe for APP_NAMES
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+To lowercase the value in-place, use make_ascii_lowercase
.
+Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for APP_NAMES
§impl Send for APP_NAMES
§impl Sync for APP_NAMES
§impl Unpin for APP_NAMES
§impl UnwindSafe for APP_NAMES
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/macro.print.html b/ch5/os/macro.print.html
index e95368c8..be9fdef8 100644
--- a/ch5/os/macro.print.html
+++ b/ch5/os/macro.print.html
@@ -1,5 +1,4 @@
-print in os - Rust
\ No newline at end of file
+print in os - Rust
\ No newline at end of file
diff --git a/ch5/os/macro.println.html b/ch5/os/macro.println.html
index c11546c7..2117ac86 100644
--- a/ch5/os/macro.println.html
+++ b/ch5/os/macro.println.html
@@ -1,5 +1,4 @@
-println in os - Rust
\ No newline at end of file
+println in os - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/constant.PA_WIDTH_SV39.html b/ch5/os/mm/address/constant.PA_WIDTH_SV39.html
index 8b089bc7..bf92fdf9 100644
--- a/ch5/os/mm/address/constant.PA_WIDTH_SV39.html
+++ b/ch5/os/mm/address/constant.PA_WIDTH_SV39.html
@@ -1,2 +1,2 @@
-PA_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
+PA_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/constant.PPN_WIDTH_SV39.html b/ch5/os/mm/address/constant.PPN_WIDTH_SV39.html
index b17cc01a..23c5ffdd 100644
--- a/ch5/os/mm/address/constant.PPN_WIDTH_SV39.html
+++ b/ch5/os/mm/address/constant.PPN_WIDTH_SV39.html
@@ -1 +1 @@
-PPN_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
+PPN_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/constant.VA_WIDTH_SV39.html b/ch5/os/mm/address/constant.VA_WIDTH_SV39.html
index abea1f5c..f2a5525e 100644
--- a/ch5/os/mm/address/constant.VA_WIDTH_SV39.html
+++ b/ch5/os/mm/address/constant.VA_WIDTH_SV39.html
@@ -1 +1 @@
-VA_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
+VA_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/constant.VPN_WIDTH_SV39.html b/ch5/os/mm/address/constant.VPN_WIDTH_SV39.html
index e9f70312..b8b1ba49 100644
--- a/ch5/os/mm/address/constant.VPN_WIDTH_SV39.html
+++ b/ch5/os/mm/address/constant.VPN_WIDTH_SV39.html
@@ -1 +1 @@
-VPN_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
+VPN_WIDTH_SV39 in os::mm::address - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/index.html b/ch5/os/mm/address/index.html
index 24c01bf2..3fd00c75 100644
--- a/ch5/os/mm/address/index.html
+++ b/ch5/os/mm/address/index.html
@@ -1,10 +1,2 @@
-os::mm::address - Rust Expand description
Implementation of physical and virtual address and page number.
-Structs
physical address
-physical page number
-a simple range structure for type T
-iterator for the simple range structure
-virtual address
-virtual page number
-Constants
Traits
Type Definitions
a simple range structure for virtual page number
-
\ No newline at end of file
+os::mm::address - Rust Expand description
Implementation of physical and virtual address and page number.
+Structs
- physical address
- physical page number
- a simple range structure for type T
- iterator for the simple range structure
- virtual address
- virtual page number
Constants
- physical address
Traits
Type Aliases
- a simple range structure for virtual page number
\ No newline at end of file
diff --git a/ch5/os/mm/address/sidebar-items.js b/ch5/os/mm/address/sidebar-items.js
index e11536d5..60e19a5a 100644
--- a/ch5/os/mm/address/sidebar-items.js
+++ b/ch5/os/mm/address/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"constant":[["PA_WIDTH_SV39","physical address"],["PPN_WIDTH_SV39",""],["VA_WIDTH_SV39",""],["VPN_WIDTH_SV39",""]],"struct":[["PhysAddr","physical address"],["PhysPageNum","physical page number"],["SimpleRange","a simple range structure for type T"],["SimpleRangeIterator","iterator for the simple range structure"],["VirtAddr","virtual address"],["VirtPageNum","virtual page number"]],"trait":[["StepByOne",""]],"type":[["VPNRange","a simple range structure for virtual page number"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"constant":["PA_WIDTH_SV39","PPN_WIDTH_SV39","VA_WIDTH_SV39","VPN_WIDTH_SV39"],"struct":["PhysAddr","PhysPageNum","SimpleRange","SimpleRangeIterator","VirtAddr","VirtPageNum"],"trait":["StepByOne"],"type":["VPNRange"]};
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.PhysAddr.html b/ch5/os/mm/address/struct.PhysAddr.html
index 3ddd87e7..a306590f 100644
--- a/ch5/os/mm/address/struct.PhysAddr.html
+++ b/ch5/os/mm/address/struct.PhysAddr.html
@@ -1,45 +1,28 @@
-PhysAddr in os::mm::address - Rust pub struct PhysAddr(pub usize);
Expand description
physical address
-Tuple Fields
0: usize
Implementations
sourceimpl PhysAddr
sourcepub fn floor(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
-sourcepub fn ceil(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
-sourcepub fn page_offset(&self) -> usize
Get page offset
-sourceimpl PhysAddr
sourcepub fn get_mut<T>(&self) -> &'static mut T
Get mutable reference to PhysAddr
value
-Trait Implementations
sourceimpl From<PhysAddr> for PhysPageNum
sourceimpl From<PhysPageNum> for PhysAddr
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for PhysAddr
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
+
PhysAddr in os::mm::address - Rust pub struct PhysAddr(pub usize);
Expand description
physical address
+Tuple Fields§
§0: usize
Implementations§
source§impl PhysAddr
sourcepub fn floor(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
+sourcepub fn ceil(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
+sourcepub fn page_offset(&self) -> usize
Get page offset
+Trait Implementations§
source§impl From<PhysAddr> for PhysPageNum
source§impl From<PhysPageNum> for PhysAddr
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for PhysAddr
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
T -> usize: T.0
usize -> T: usize.into()
-sourceimpl Ord for PhysAddr
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialOrd<PhysAddr> for PhysAddr
sourcefn partial_cmp(&self, other: &PhysAddr) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for PhysAddr
sourceimpl Eq for PhysAddr
sourceimpl StructuralEq for PhysAddr
sourceimpl StructuralPartialEq for PhysAddr
Auto Trait Implementations
impl RefUnwindSafe for PhysAddr
impl Send for PhysAddr
impl Sync for PhysAddr
impl Unpin for PhysAddr
impl UnwindSafe for PhysAddr
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
source§impl Ord for PhysAddr
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PhysAddr> for PhysAddr
source§impl PartialOrd<PhysAddr> for PhysAddr
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for PhysAddr
source§impl Eq for PhysAddr
source§impl StructuralEq for PhysAddr
source§impl StructuralPartialEq for PhysAddr
Auto Trait Implementations§
§impl RefUnwindSafe for PhysAddr
§impl Send for PhysAddr
§impl Sync for PhysAddr
§impl Unpin for PhysAddr
§impl UnwindSafe for PhysAddr
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.PhysPageNum.html b/ch5/os/mm/address/struct.PhysPageNum.html
index 81cf94ea..f94a3b79 100644
--- a/ch5/os/mm/address/struct.PhysPageNum.html
+++ b/ch5/os/mm/address/struct.PhysPageNum.html
@@ -1,38 +1,21 @@
-PhysPageNum in os::mm::address - Rust pub struct PhysPageNum(pub usize);
Expand description
physical page number
-Tuple Fields
0: usize
Implementations
sourceimpl PhysPageNum
sourcepub fn get_pte_array(&self) -> &'static mut [PageTableEntry]
Get PageTableEntry
on PhysPageNum
-sourcepub fn get_bytes_array(&self) -> &'static mut [u8]
sourcepub fn get_mut<T>(&self) -> &'static mut T
Trait Implementations
sourceimpl Clone for PhysPageNum
sourcefn clone(&self) -> PhysPageNum
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for PhysPageNum
sourceimpl From<PhysAddr> for PhysPageNum
sourceimpl From<PhysPageNum> for PhysAddr
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<PhysPageNum> for usize
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for PhysPageNum
sourceimpl Ord for PhysPageNum
sourcefn cmp(&self, other: &PhysPageNum) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<PhysPageNum> for PhysPageNum
sourcefn eq(&self, other: &PhysPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &PhysPageNum) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<PhysPageNum> for PhysPageNum
sourcefn partial_cmp(&self, other: &PhysPageNum) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for PhysPageNum
sourceimpl Eq for PhysPageNum
sourceimpl StructuralEq for PhysPageNum
sourceimpl StructuralPartialEq for PhysPageNum
Auto Trait Implementations
impl RefUnwindSafe for PhysPageNum
impl Send for PhysPageNum
impl Sync for PhysPageNum
impl Unpin for PhysPageNum
impl UnwindSafe for PhysPageNum
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+PhysPageNum in os::mm::address - Rust Struct os::mm::address::PhysPageNum
source · pub struct PhysPageNum(pub usize);
Expand description
physical page number
+Tuple Fields§
§0: usize
Implementations§
source§impl PhysPageNum
sourcepub fn get_pte_array(&self) -> &'static mut [PageTableEntry]
Get PageTableEntry
on PhysPageNum
+sourcepub fn get_bytes_array(&self) -> &'static mut [u8]
sourcepub fn get_mut<T>(&self) -> &'static mut T
Trait Implementations§
source§impl Clone for PhysPageNum
source§fn clone(&self) -> PhysPageNum
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for PhysPageNum
source§impl From<PhysAddr> for PhysPageNum
source§impl From<PhysPageNum> for PhysAddr
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<PhysPageNum> for usize
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for PhysPageNum
source§impl Ord for PhysPageNum
source§fn cmp(&self, other: &PhysPageNum) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PhysPageNum> for PhysPageNum
source§fn eq(&self, other: &PhysPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<PhysPageNum> for PhysPageNum
source§fn partial_cmp(&self, other: &PhysPageNum) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for PhysPageNum
source§impl Eq for PhysPageNum
source§impl StructuralEq for PhysPageNum
source§impl StructuralPartialEq for PhysPageNum
Auto Trait Implementations§
§impl RefUnwindSafe for PhysPageNum
§impl Send for PhysPageNum
§impl Sync for PhysPageNum
§impl Unpin for PhysPageNum
§impl UnwindSafe for PhysPageNum
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.SimpleRange.html b/ch5/os/mm/address/struct.SimpleRange.html
index 149264e1..76a20c20 100644
--- a/ch5/os/mm/address/struct.SimpleRange.html
+++ b/ch5/os/mm/address/struct.SimpleRange.html
@@ -1,24 +1,26 @@
-SimpleRange in os::mm::address - Rust pub struct SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
+SimpleRange in os::mm::address - Rust Struct os::mm::address::SimpleRange
source · pub struct SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,{
l: T,
r: T,
-}
Expand description
a simple range structure for type T
-Fields
l: T
r: T
Implementations
Trait Implementations
sourceimpl<T: Clone> Clone for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
sourcefn clone(&self) -> SimpleRange<T>
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl<T> IntoIterator for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
sourceimpl<T: Copy> Copy for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Auto Trait Implementations
impl<T> RefUnwindSafe for SimpleRange<T> where
T: RefUnwindSafe,
impl<T> Send for SimpleRange<T> where
T: Send,
impl<T> Sync for SimpleRange<T> where
T: Sync,
impl<T> Unpin for SimpleRange<T> where
T: Unpin,
impl<T> UnwindSafe for SimpleRange<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a simple range structure for type T
+Fields§
§l: T
§r: T
Implementations§
Trait Implementations§
source§impl<T> Clone for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Clone,
source§fn clone(&self) -> SimpleRange<T>
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl<T> IntoIterator for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
source§impl<T> Copy for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Copy,
Auto Trait Implementations§
§impl<T> RefUnwindSafe for SimpleRange<T>where
+ T: RefUnwindSafe,
§impl<T> Send for SimpleRange<T>where
+ T: Send,
§impl<T> Sync for SimpleRange<T>where
+ T: Sync,
§impl<T> Unpin for SimpleRange<T>where
+ T: Unpin,
§impl<T> UnwindSafe for SimpleRange<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.SimpleRangeIterator.html b/ch5/os/mm/address/struct.SimpleRangeIterator.html
index 6d685cb5..e31164ea 100644
--- a/ch5/os/mm/address/struct.SimpleRangeIterator.html
+++ b/ch5/os/mm/address/struct.SimpleRangeIterator.html
@@ -1,132 +1,201 @@
-SimpleRangeIterator in os::mm::address - Rust pub struct SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
+SimpleRangeIterator in os::mm::address - Rust Struct os::mm::address::SimpleRangeIterator
source · pub struct SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,{
current: T,
end: T,
-}
Expand description
iterator for the simple range structure
-Fields
current: T
end: T
Implementations
sourceimpl<T> SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Trait Implementations
sourceimpl<T> Iterator for SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
type Item = T
The type of the elements being iterated over.
-sourcefn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read more
-sourcefn next_chunk<const N: usize>(
&mut self
) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
🔬 This is a nightly-only experimental API. (iter_next_chunk
)Advances the iterator and returns an array containing the next N
values. Read more
-1.0.0 · sourcefn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more
-1.0.0 · sourcefn count(self) -> usize
Consumes the iterator, counting the number of iterations and returning it. Read more
-1.0.0 · sourcefn last(self) -> Option<Self::Item>
Consumes the iterator, returning the last element. Read more
-sourcefn advance_by(&mut self, n: usize) -> Result<(), usize>
🔬 This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more
-1.0.0 · sourcefn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more
-1.28.0 · sourcefn step_by(self, step: usize) -> StepBy<Self>
Creates an iterator starting at the same point, but stepping by
-the given amount at each iteration. Read more
-1.0.0 · sourcefn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more
-1.0.0 · sourcefn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read more
-sourcefn intersperse(self, separator: Self::Item) -> Intersperse<Self> where
Self::Item: Clone,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
-items of the original iterator. Read more
-sourcefn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where
G: FnMut() -> Self::Item,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
-between adjacent items of the original iterator. Read more
-1.0.0 · sourcefn map<B, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
-element. Read more
-1.21.0 · sourcefn for_each<F>(self, f: F) where
F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more
-1.0.0 · sourcefn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
-should be yielded. Read more
-1.0.0 · sourcefn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more
-1.0.0 · sourcefn enumerate(self) -> Enumerate<Self>
Creates an iterator which gives the current iteration count as well as
-the next value. Read more
-1.0.0 · sourcefn peekable(self) -> Peekable<Self>
Creates an iterator which can use the peek
and peek_mut
methods
+}Expand description
iterator for the simple range structure
+
Fields§
§current: T
§end: T
Implementations§
source§impl<T> SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Trait Implementations§
source§impl<T> Iterator for SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
source§fn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read moresource§fn next_chunk<const N: usize>(
+ &mut self
+) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_next_chunk
)Advances the iterator and returns an array containing the next N
values. Read more1.0.0 · source§fn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more1.0.0 · source§fn count(self) -> usizewhere
+ Self: Sized,
Consumes the iterator, counting the number of iterations and returning it. Read more1.0.0 · source§fn last(self) -> Option<Self::Item>where
+ Self: Sized,
Consumes the iterator, returning the last element. Read moresource§fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
🔬This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more1.0.0 · source§fn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more1.28.0 · source§fn step_by(self, step: usize) -> StepBy<Self>where
+ Self: Sized,
Creates an iterator starting at the same point, but stepping by
+the given amount at each iteration. Read more1.0.0 · source§fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more1.0.0 · source§fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read moresource§fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where
+ Self: Sized,
+ G: FnMut() -> Self::Item,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
+between adjacent items of the original iterator. Read more1.0.0 · source§fn map<B, F>(self, f: F) -> Map<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
+element. Read more1.21.0 · source§fn for_each<F>(self, f: F)where
+ Self: Sized,
+ F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more1.0.0 · source§fn filter<P>(self, predicate: P) -> Filter<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
+should be yielded. Read more1.0.0 · source§fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more1.0.0 · source§fn enumerate(self) -> Enumerate<Self>where
+ Self: Sized,
Creates an iterator which gives the current iteration count as well as
+the next value. Read more1.0.0 · sourcefn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0 · sourcefn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more
-1.57.0 · sourcefn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where
P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more
-1.0.0 · sourcefn skip(self, n: usize) -> Skip<Self>
Creates an iterator that skips the first n
elements. Read more
-1.0.0 · sourcefn take(self, n: usize) -> Take<Self>
Creates an iterator that yields the first n
elements, or fewer
-if the underlying iterator ends sooner. Read more
-1.0.0 · sourcefn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · sourcefn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
U: IntoIterator,
F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read more
-1.29.0 · sourcefn flatten(self) -> Flatten<Self> where
Self::Item: IntoIterator,
Creates an iterator that flattens nested structure. Read more
-1.0.0 · sourcefn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more
-1.0.0 · sourcefn by_ref(&mut self) -> &mut Self
Borrows an iterator, rather than consuming it. Read more
-1.0.0 · sourcefn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
Transforms an iterator into a collection. Read more
-sourcefn try_collect<B>(
&mut self
) -> <<Self::Item as Try>::Residual as Residual<B>>::TryType where
B: FromIterator<<Self::Item as Try>::Output>,
Self::Item: Try,
<Self::Item as Try>::Residual: Residual<B>,
🔬 This is a nightly-only experimental API. (iterator_try_collect
)Fallibly transforms an iterator into a collection, short circuiting if
-a failure is encountered. Read more
-sourcefn collect_into<E>(self, collection: &mut E) -> &mut E where
E: Extend<Self::Item>,
🔬 This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more
-1.0.0 · sourcefn partition<B, F>(self, f: F) -> (B, B) where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read more
-sourcefn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
🔬 This is a nightly-only experimental API. (iter_partition_in_place
)Reorders the elements of this iterator in-place according to the given predicate,
-such that all those that return true
precede all those that return false
.
-Returns the number of true
elements found. Read more
-sourcefn is_partitioned<P>(self, predicate: P) -> bool where
P: FnMut(Self::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
-such that all those that return true
precede all those that return false
. Read more
-1.27.0 · sourcefn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
An iterator method that applies a function as long as it returns
-successfully, producing a single, final value. Read more
-1.27.0 · sourcefn try_for_each<F, R>(&mut self, f: F) -> R where
F: FnMut(Self::Item) -> R,
R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
-iterator, stopping at the first error and returning that error. Read more
-1.0.0 · sourcefn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
-returning the final result. Read more
-1.51.0 · sourcefn reduce<F>(self, f: F) -> Option<Self::Item> where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
-operation. Read more
-sourcefn try_reduce<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType where
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
-closure returns a failure, the failure is propagated back to the caller immediately. Read more
-1.0.0 · sourcefn all<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn any<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more
-1.30.0 · sourcefn find_map<B, F>(&mut self, f: F) -> Option<B> where
F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
-the first non-none result. Read more
-sourcefn try_find<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType where
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
-the first true result or the first error. Read more
-1.0.0 · sourcefn position<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more
-1.0.0 · sourcefn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
Searches for an element in an iterator from the right, returning its
-index. Read more
-1.0.0 · sourcefn max(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the maximum element of an iterator. Read more
-1.0.0 · sourcefn min(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the minimum element of an iterator. Read more
-1.6.0 · sourcefn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
-specified function. Read more
-1.15.0 · sourcefn max_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
-specified comparison function. Read more
-1.6.0 · sourcefn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
-specified function. Read more
-1.15.0 · sourcefn min_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
-specified comparison function. Read more
-1.0.0 · sourcefn rev(self) -> Rev<Self> where
Self: DoubleEndedIterator,
Reverses an iterator’s direction. Read more
-1.0.0 · sourcefn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more
-1.36.0 · sourcefn copied<'a, T>(self) -> Copied<Self> where
T: 'a + Copy,
Self: Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more
-1.0.0 · sourcefn cloned<'a, T>(self) -> Cloned<Self> where
T: 'a + Clone,
Self: Iterator<Item = &'a T>,
1.0.0 · sourcefn cycle(self) -> Cycle<Self> where
Self: Clone,
Repeats an iterator endlessly. Read more
-1.11.0 · sourcefn sum<S>(self) -> S where
S: Sum<Self::Item>,
Sums the elements of an iterator. Read more
-1.11.0 · sourcefn product<P>(self) -> P where
P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more
-1.5.0 · sourcefn cmp<I>(self, other: I) -> Ordering where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
sourcefn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_order_by
)1.5.0 · sourcefn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0 · sourcefn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less than those of another. Read more
-1.5.0 · sourcefn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less or equal to those of another. Read more
-1.5.0 · sourcefn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than those of another. Read more
-1.5.0 · sourcefn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than or equal to those of another. Read more
-sourcefn is_sorted(self) -> bool where
Self::Item: PartialOrd<Self::Item>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read more
-sourcefn is_sorted_by<F>(self, compare: F) -> bool where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read more
-sourcefn is_sorted_by_key<F, K>(self, f: F) -> bool where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
-function. Read more
-Auto Trait Implementations
impl<T> RefUnwindSafe for SimpleRangeIterator<T> where
T: RefUnwindSafe,
impl<T> Send for SimpleRangeIterator<T> where
T: Send,
impl<T> Sync for SimpleRangeIterator<T> where
T: Sync,
impl<T> Unpin for SimpleRangeIterator<T> where
T: Unpin,
impl<T> UnwindSafe for SimpleRangeIterator<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+their documentation for more information. Read more1.0.0 · source§fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
1.0.0 · source§fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more1.57.0 · source§fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more1.0.0 · source§fn skip(self, n: usize) -> Skip<Self>where
+ Self: Sized,
Creates an iterator that skips the first n
elements. Read more1.0.0 · source§fn take(self, n: usize) -> Take<Self>where
+ Self: Sized,
Creates an iterator that yields the first n
elements, or fewer
+if the underlying iterator ends sooner. Read more1.0.0 · source§fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where
+ Self: Sized,
+ F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · source§fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where
+ Self: Sized,
+ U: IntoIterator,
+ F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read moresource§fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where
+ Self: Sized,
+ F: FnMut(&[Self::Item; N]) -> R,
🔬This is a nightly-only experimental API. (iter_map_windows
)Calls the given function f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read more1.0.0 · source§fn inspect<F>(self, f: F) -> Inspect<Self, F>where
+ Self: Sized,
+ F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more1.0.0 · source§fn by_ref(&mut self) -> &mut Selfwhere
+ Self: Sized,
Borrows an iterator, rather than consuming it. Read more1.0.0 · source§fn collect<B>(self) -> Bwhere
+ B: FromIterator<Self::Item>,
+ Self: Sized,
Transforms an iterator into a collection. Read moresource§fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere
+ E: Extend<Self::Item>,
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more1.0.0 · source§fn partition<B, F>(self, f: F) -> (B, B)where
+ Self: Sized,
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read moresource§fn is_partitioned<P>(self, predicate: P) -> boolwhere
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
+such that all those that return true
precede all those that return false
. Read more1.27.0 · source§fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
An iterator method that applies a function as long as it returns
+successfully, producing a single, final value. Read more1.27.0 · source§fn try_for_each<F, R>(&mut self, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> R,
+ R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
+iterator, stopping at the first error and returning that error. Read more1.0.0 · source§fn fold<B, F>(self, init: B, f: F) -> Bwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
+returning the final result. Read more1.51.0 · source§fn reduce<F>(self, f: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
+operation. Read moresource§fn try_reduce<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> R,
+ R: Try<Output = Self::Item>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
+closure returns a failure, the failure is propagated back to the caller immediately. Read more1.0.0 · source§fn all<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more1.0.0 · source§fn any<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more1.0.0 · source§fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more1.30.0 · source§fn find_map<B, F>(&mut self, f: F) -> Option<B>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
+the first non-none result. Read moresource§fn try_find<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(&Self::Item) -> R,
+ R: Try<Output = bool>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
+the first true result or the first error. Read more1.0.0 · source§fn position<P>(&mut self, predicate: P) -> Option<usize>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more1.6.0 · source§fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
+specified function. Read more1.15.0 · source§fn max_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
+specified comparison function. Read more1.6.0 · source§fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
+specified function. Read more1.15.0 · source§fn min_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
+specified comparison function. Read more1.0.0 · source§fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
+ Self: Sized + Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more1.36.0 · source§fn copied<'a, T>(self) -> Copied<Self>where
+ T: 'a + Copy,
+ Self: Sized + Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more1.0.0 · source§fn cloned<'a, T>(self) -> Cloned<Self>where
+ T: 'a + Clone,
+ Self: Sized + Iterator<Item = &'a T>,
source§fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_array_chunks
)Returns an iterator over N
elements of the iterator at a time. Read more1.11.0 · source§fn sum<S>(self) -> Swhere
+ Self: Sized,
+ S: Sum<Self::Item>,
Sums the elements of an iterator. Read more1.11.0 · source§fn product<P>(self) -> Pwhere
+ Self: Sized,
+ P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read moresource§fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn partial_cmp<I>(self, other: I) -> Option<Ordering>where
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Lexicographically compares the PartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moresource§fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn eq<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
source§fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_order_by
)1.5.0 · source§fn ne<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
1.5.0 · source§fn lt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less than those of another. Read more1.5.0 · source§fn le<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less or equal to those of another. Read more1.5.0 · source§fn gt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than those of another. Read more1.5.0 · source§fn ge<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than or equal to those of another. Read moresource§fn is_sorted_by<F>(self, compare: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read moresource§fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> K,
+ K: PartialOrd<K>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
+function. Read moreAuto Trait Implementations§
§impl<T> RefUnwindSafe for SimpleRangeIterator<T>where
+ T: RefUnwindSafe,
§impl<T> Send for SimpleRangeIterator<T>where
+ T: Send,
§impl<T> Sync for SimpleRangeIterator<T>where
+ T: Sync,
§impl<T> Unpin for SimpleRangeIterator<T>where
+ T: Unpin,
§impl<T> UnwindSafe for SimpleRangeIterator<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<I> IntoIterator for I where
I: Iterator,
\ No newline at end of file
+From<T> for U
chooses to do.
+source§impl<I> IntoIterator for Iwhere
+ I: Iterator,
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.VirtAddr.html b/ch5/os/mm/address/struct.VirtAddr.html
index 89b47417..ca4158f8 100644
--- a/ch5/os/mm/address/struct.VirtAddr.html
+++ b/ch5/os/mm/address/struct.VirtAddr.html
@@ -1,42 +1,25 @@
-VirtAddr in os::mm::address - Rust pub struct VirtAddr(pub usize);
Expand description
virtual address
-Tuple Fields
0: usize
Implementations
sourceimpl VirtAddr
sourcepub fn floor(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
-sourcepub fn ceil(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
-sourcepub fn page_offset(&self) -> usize
Get page offset
-Trait Implementations
sourceimpl From<VirtAddr> for VirtPageNum
sourceimpl From<VirtPageNum> for VirtAddr
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl Ord for VirtAddr
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialOrd<VirtAddr> for VirtAddr
sourcefn partial_cmp(&self, other: &VirtAddr) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for VirtAddr
sourceimpl Eq for VirtAddr
sourceimpl StructuralEq for VirtAddr
sourceimpl StructuralPartialEq for VirtAddr
Auto Trait Implementations
impl RefUnwindSafe for VirtAddr
impl Send for VirtAddr
impl Sync for VirtAddr
impl Unpin for VirtAddr
impl UnwindSafe for VirtAddr
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+VirtAddr in os::mm::address - Rust pub struct VirtAddr(pub usize);
Expand description
virtual address
+Tuple Fields§
§0: usize
Implementations§
source§impl VirtAddr
sourcepub fn floor(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
+sourcepub fn ceil(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
+sourcepub fn page_offset(&self) -> usize
Get page offset
+Trait Implementations§
source§impl From<VirtAddr> for VirtPageNum
source§impl From<VirtPageNum> for VirtAddr
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl Ord for VirtAddr
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<VirtAddr> for VirtAddr
source§impl PartialOrd<VirtAddr> for VirtAddr
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for VirtAddr
source§impl Eq for VirtAddr
source§impl StructuralEq for VirtAddr
source§impl StructuralPartialEq for VirtAddr
Auto Trait Implementations§
§impl RefUnwindSafe for VirtAddr
§impl Send for VirtAddr
§impl Sync for VirtAddr
§impl Unpin for VirtAddr
§impl UnwindSafe for VirtAddr
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/address/struct.VirtPageNum.html b/ch5/os/mm/address/struct.VirtPageNum.html
index cb7be603..55e6f75e 100644
--- a/ch5/os/mm/address/struct.VirtPageNum.html
+++ b/ch5/os/mm/address/struct.VirtPageNum.html
@@ -1,38 +1,21 @@
-VirtPageNum in os::mm::address - Rust pub struct VirtPageNum(pub usize);
Expand description
virtual page number
-Tuple Fields
0: usize
Implementations
Trait Implementations
sourceimpl Clone for VirtPageNum
sourcefn clone(&self) -> VirtPageNum
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for VirtPageNum
sourceimpl From<VirtAddr> for VirtPageNum
sourceimpl From<VirtPageNum> for VirtAddr
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<VirtPageNum> for usize
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for VirtPageNum
sourceimpl Ord for VirtPageNum
sourcefn cmp(&self, other: &VirtPageNum) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<VirtPageNum> for VirtPageNum
sourcefn eq(&self, other: &VirtPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &VirtPageNum) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<VirtPageNum> for VirtPageNum
sourcefn partial_cmp(&self, other: &VirtPageNum) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl StepByOne for VirtPageNum
sourceimpl Copy for VirtPageNum
sourceimpl Eq for VirtPageNum
sourceimpl StructuralEq for VirtPageNum
sourceimpl StructuralPartialEq for VirtPageNum
Auto Trait Implementations
impl RefUnwindSafe for VirtPageNum
impl Send for VirtPageNum
impl Sync for VirtPageNum
impl Unpin for VirtPageNum
impl UnwindSafe for VirtPageNum
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+VirtPageNum in os::mm::address - Rust Struct os::mm::address::VirtPageNum
source · pub struct VirtPageNum(pub usize);
Expand description
virtual page number
+Tuple Fields§
§0: usize
Implementations§
Trait Implementations§
source§impl Clone for VirtPageNum
source§fn clone(&self) -> VirtPageNum
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for VirtPageNum
source§impl From<VirtAddr> for VirtPageNum
source§impl From<VirtPageNum> for VirtAddr
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl From<VirtPageNum> for usize
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for VirtPageNum
source§impl Ord for VirtPageNum
source§fn cmp(&self, other: &VirtPageNum) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<VirtPageNum> for VirtPageNum
source§fn eq(&self, other: &VirtPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<VirtPageNum> for VirtPageNum
source§fn partial_cmp(&self, other: &VirtPageNum) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for VirtPageNum
source§impl Eq for VirtPageNum
source§impl StructuralEq for VirtPageNum
source§impl StructuralPartialEq for VirtPageNum
Auto Trait Implementations§
§impl RefUnwindSafe for VirtPageNum
§impl Send for VirtPageNum
§impl Sync for VirtPageNum
§impl Unpin for VirtPageNum
§impl UnwindSafe for VirtPageNum
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/address/trait.StepByOne.html b/ch5/os/mm/address/trait.StepByOne.html
index 4d0a6b8a..17274594 100644
--- a/ch5/os/mm/address/trait.StepByOne.html
+++ b/ch5/os/mm/address/trait.StepByOne.html
@@ -1,3 +1,4 @@
-StepByOne in os::mm::address - Rust
\ No newline at end of file
+StepByOne in os::mm::address - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/address/type.VPNRange.html b/ch5/os/mm/address/type.VPNRange.html
index 4c732695..375df987 100644
--- a/ch5/os/mm/address/type.VPNRange.html
+++ b/ch5/os/mm/address/type.VPNRange.html
@@ -1,2 +1,9 @@
-VPNRange in os::mm::address - Rust pub type VPNRange = SimpleRange<VirtPageNum>;
Expand description
a simple range structure for virtual page number
-
\ No newline at end of file
+VPNRange in os::mm::address - Rust pub type VPNRange = SimpleRange<VirtPageNum>;
Expand description
a simple range structure for virtual page number
+Aliased Type§
struct VPNRange {
+ l: VirtPageNum,
+ r: VirtPageNum,
+}
Fields§
§l: VirtPageNum
§r: VirtPageNum
Implementations§
Trait Implementations§
source§impl<T> Clone for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Clone,
source§fn clone(&self) -> SimpleRange<T>
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl<T> IntoIterator for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
source§impl<T> Copy for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Copy,
\ No newline at end of file
diff --git a/ch5/os/mm/fn.frame_alloc.html b/ch5/os/mm/fn.frame_alloc.html
index 3126dfa9..c85dde37 100644
--- a/ch5/os/mm/fn.frame_alloc.html
+++ b/ch5/os/mm/fn.frame_alloc.html
@@ -1,2 +1,2 @@
-frame_alloc in os::mm - Rust Function os::mm::frame_alloc
source · [−]pub fn frame_alloc() -> Option<FrameTracker>
Expand description
allocate a frame
-
\ No newline at end of file
+frame_alloc in os::mm - Rust Function os::mm::frame_alloc
source · pub fn frame_alloc() -> Option<FrameTracker>
Expand description
allocate a frame
+
\ No newline at end of file
diff --git a/ch5/os/mm/fn.init.html b/ch5/os/mm/fn.init.html
index a1c0bb1f..bbb442bd 100644
--- a/ch5/os/mm/fn.init.html
+++ b/ch5/os/mm/fn.init.html
@@ -1,2 +1,2 @@
-init in os::mm - Rust
\ No newline at end of file
+init in os::mm - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/fn.remap_test.html b/ch5/os/mm/fn.remap_test.html
index 10f46eff..dd6a9410 100644
--- a/ch5/os/mm/fn.remap_test.html
+++ b/ch5/os/mm/fn.remap_test.html
@@ -1,2 +1,2 @@
-remap_test in os::mm - Rust Function os::mm::remap_test
source · [−]pub fn remap_test()
Expand description
Check PageTable running correctly
-
\ No newline at end of file
+remap_test in os::mm - Rust Function os::mm::remap_test
source · pub fn remap_test()
Expand description
Check PageTable running correctly
+
\ No newline at end of file
diff --git a/ch5/os/mm/fn.translated_byte_buffer.html b/ch5/os/mm/fn.translated_byte_buffer.html
index 06950317..132ad6c5 100644
--- a/ch5/os/mm/fn.translated_byte_buffer.html
+++ b/ch5/os/mm/fn.translated_byte_buffer.html
@@ -1,2 +1,6 @@
-translated_byte_buffer in os::mm - Rust
\ No newline at end of file
+translated_byte_buffer in os::mm - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/fn.translated_refmut.html b/ch5/os/mm/fn.translated_refmut.html
index 75749984..df1ed019 100644
--- a/ch5/os/mm/fn.translated_refmut.html
+++ b/ch5/os/mm/fn.translated_refmut.html
@@ -1,2 +1,2 @@
-translated_refmut in os::mm - Rust Function os::mm::translated_refmut
source · [−]pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Expand description
translate a generic through page table and return a mutable reference
-
\ No newline at end of file
+translated_refmut in os::mm - Rust Function os::mm::translated_refmut
source · pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Expand description
translate a generic through page table and return a mutable reference
+
\ No newline at end of file
diff --git a/ch5/os/mm/fn.translated_str.html b/ch5/os/mm/fn.translated_str.html
index 1dbb9a24..bf957511 100644
--- a/ch5/os/mm/fn.translated_str.html
+++ b/ch5/os/mm/fn.translated_str.html
@@ -1,2 +1,2 @@
-translated_str in os::mm - Rust
\ No newline at end of file
+translated_str in os::mm - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/fn.frame_alloc.html b/ch5/os/mm/frame_allocator/fn.frame_alloc.html
index e6207176..b611ff59 100644
--- a/ch5/os/mm/frame_allocator/fn.frame_alloc.html
+++ b/ch5/os/mm/frame_allocator/fn.frame_alloc.html
@@ -1,2 +1,2 @@
-frame_alloc in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_alloc
source · [−]pub fn frame_alloc() -> Option<FrameTracker>
Expand description
allocate a frame
-
\ No newline at end of file
+frame_alloc in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_alloc
source · pub fn frame_alloc() -> Option<FrameTracker>
Expand description
allocate a frame
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/fn.frame_allocator_test.html b/ch5/os/mm/frame_allocator/fn.frame_allocator_test.html
index ad420f38..e4ebf6de 100644
--- a/ch5/os/mm/frame_allocator/fn.frame_allocator_test.html
+++ b/ch5/os/mm/frame_allocator/fn.frame_allocator_test.html
@@ -1,2 +1,2 @@
-frame_allocator_test in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_allocator_test
source · [−]pub fn frame_allocator_test()
Expand description
a simple test for frame allocator
-
\ No newline at end of file
+frame_allocator_test in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_allocator_test
source · pub fn frame_allocator_test()
Expand description
a simple test for frame allocator
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/fn.frame_dealloc.html b/ch5/os/mm/frame_allocator/fn.frame_dealloc.html
index 5f96995e..51835260 100644
--- a/ch5/os/mm/frame_allocator/fn.frame_dealloc.html
+++ b/ch5/os/mm/frame_allocator/fn.frame_dealloc.html
@@ -1,2 +1,2 @@
-frame_dealloc in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_dealloc
source · [−]fn frame_dealloc(ppn: PhysPageNum)
Expand description
deallocate a frame
-
\ No newline at end of file
+frame_dealloc in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::frame_dealloc
source · fn frame_dealloc(ppn: PhysPageNum)
Expand description
deallocate a frame
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/fn.init_frame_allocator.html b/ch5/os/mm/frame_allocator/fn.init_frame_allocator.html
index 948aa858..bb1fde60 100644
--- a/ch5/os/mm/frame_allocator/fn.init_frame_allocator.html
+++ b/ch5/os/mm/frame_allocator/fn.init_frame_allocator.html
@@ -1,2 +1,2 @@
-init_frame_allocator in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::init_frame_allocator
source · [−]pub fn init_frame_allocator()
Expand description
initiate the frame allocator using ekernel
and MEMORY_END
-
\ No newline at end of file
+init_frame_allocator in os::mm::frame_allocator - Rust Function os::mm::frame_allocator::init_frame_allocator
source · pub fn init_frame_allocator()
Expand description
initiate the frame allocator using ekernel
and MEMORY_END
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/index.html b/ch5/os/mm/frame_allocator/index.html
index 82bc5387..36d9cd19 100644
--- a/ch5/os/mm/frame_allocator/index.html
+++ b/ch5/os/mm/frame_allocator/index.html
@@ -1,10 +1,3 @@
-os::mm::frame_allocator - Rust Module os::mm::frame_allocator
source · [−]Expand description
Implementation of FrameAllocator
which
+
os::mm::frame_allocator - Rust Module os::mm::frame_allocator
source · Expand description
Implementation of FrameAllocator
which
controls all the frames in the operating system.
-Structs
frame allocator instance through lazy_static!
-manage a frame which has the same lifecycle as the tracker
-an implementation for frame allocator
-Traits
Functions
allocate a frame
-a simple test for frame allocator
-deallocate a frame
-initiate the frame allocator using ekernel
and MEMORY_END
-Type Definitions
\ No newline at end of file
+Structs
- frame allocator instance through lazy_static!
- manage a frame which has the same lifecycle as the tracker
- an implementation for frame allocator
Traits
Functions
- allocate a frame
- a simple test for frame allocator
- deallocate a frame
- initiate the frame allocator using
ekernel
and MEMORY_END
Type Aliases
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/sidebar-items.js b/ch5/os/mm/frame_allocator/sidebar-items.js
index 26d4088d..be15c50b 100644
--- a/ch5/os/mm/frame_allocator/sidebar-items.js
+++ b/ch5/os/mm/frame_allocator/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["frame_alloc","allocate a frame"],["frame_allocator_test","a simple test for frame allocator"],["frame_dealloc","deallocate a frame"],["init_frame_allocator","initiate the frame allocator using `ekernel` and `MEMORY_END`"]],"struct":[["FRAME_ALLOCATOR","frame allocator instance through lazy_static!"],["FrameTracker","manage a frame which has the same lifecycle as the tracker"],["StackFrameAllocator","an implementation for frame allocator"]],"trait":[["FrameAllocator",""]],"type":[["FrameAllocatorImpl",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["frame_alloc","frame_allocator_test","frame_dealloc","init_frame_allocator"],"struct":["FRAME_ALLOCATOR","FrameTracker","StackFrameAllocator"],"trait":["FrameAllocator"],"type":["FrameAllocatorImpl"]};
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/struct.FRAME_ALLOCATOR.html b/ch5/os/mm/frame_allocator/struct.FRAME_ALLOCATOR.html
index fb04cb9f..9595de47 100644
--- a/ch5/os/mm/frame_allocator/struct.FRAME_ALLOCATOR.html
+++ b/ch5/os/mm/frame_allocator/struct.FRAME_ALLOCATOR.html
@@ -1,18 +1,15 @@
-FRAME_ALLOCATOR in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FRAME_ALLOCATOR
source · [−]pub struct FRAME_ALLOCATOR {
+FRAME_ALLOCATOR in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FRAME_ALLOCATOR
source · pub struct FRAME_ALLOCATOR {
__private_field: (),
-}
Expand description
frame allocator instance through lazy_static!
-Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<StackFrameAllocator>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for FRAME_ALLOCATOR
type Target = UPSafeCell<StackFrameAllocator>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<StackFrameAllocator>
Dereferences the value.
-sourceimpl LazyStatic for FRAME_ALLOCATOR
Auto Trait Implementations
impl RefUnwindSafe for FRAME_ALLOCATOR
impl Send for FRAME_ALLOCATOR
impl Sync for FRAME_ALLOCATOR
impl Unpin for FRAME_ALLOCATOR
impl UnwindSafe for FRAME_ALLOCATOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
frame allocator instance through lazy_static!
+Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<StackFrameAllocator>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for FRAME_ALLOCATOR
§type Target = UPSafeCell<StackFrameAllocator>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<StackFrameAllocator>
Dereferences the value.source§impl LazyStatic for FRAME_ALLOCATOR
Auto Trait Implementations§
§impl RefUnwindSafe for FRAME_ALLOCATOR
§impl Send for FRAME_ALLOCATOR
§impl Sync for FRAME_ALLOCATOR
§impl Unpin for FRAME_ALLOCATOR
§impl UnwindSafe for FRAME_ALLOCATOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/struct.FrameTracker.html b/ch5/os/mm/frame_allocator/struct.FrameTracker.html
index 9167fa1c..bfbc576a 100644
--- a/ch5/os/mm/frame_allocator/struct.FrameTracker.html
+++ b/ch5/os/mm/frame_allocator/struct.FrameTracker.html
@@ -1,18 +1,15 @@
-FrameTracker in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FrameTracker
source · [−]pub struct FrameTracker {
+FrameTracker in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FrameTracker
source · pub struct FrameTracker {
pub ppn: PhysPageNum,
-}
Expand description
manage a frame which has the same lifecycle as the tracker
-Fields
ppn: PhysPageNum
Implementations
sourceimpl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
-Trait Implementations
sourceimpl Debug for FrameTracker
Auto Trait Implementations
impl RefUnwindSafe for FrameTracker
impl Send for FrameTracker
impl Sync for FrameTracker
impl Unpin for FrameTracker
impl UnwindSafe for FrameTracker
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
manage a frame which has the same lifecycle as the tracker
+Fields§
§ppn: PhysPageNum
Implementations§
source§impl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
+Trait Implementations§
source§impl Debug for FrameTracker
Auto Trait Implementations§
§impl RefUnwindSafe for FrameTracker
§impl Send for FrameTracker
§impl Sync for FrameTracker
§impl Unpin for FrameTracker
§impl UnwindSafe for FrameTracker
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/struct.StackFrameAllocator.html b/ch5/os/mm/frame_allocator/struct.StackFrameAllocator.html
index ca477e22..935b87bd 100644
--- a/ch5/os/mm/frame_allocator/struct.StackFrameAllocator.html
+++ b/ch5/os/mm/frame_allocator/struct.StackFrameAllocator.html
@@ -1,17 +1,16 @@
-StackFrameAllocator in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::StackFrameAllocator
source · [−]pub struct StackFrameAllocator {
+StackFrameAllocator in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::StackFrameAllocator
source · pub struct StackFrameAllocator {
current: usize,
end: usize,
recycled: Vec<usize>,
-}
Expand description
an implementation for frame allocator
-Fields
current: usize
end: usize
recycled: Vec<usize>
Implementations
sourceimpl StackFrameAllocator
sourcepub fn init(&mut self, l: PhysPageNum, r: PhysPageNum)
Trait Implementations
sourceimpl FrameAllocator for StackFrameAllocator
sourcefn new() -> Self
sourcefn alloc(&mut self) -> Option<PhysPageNum>
sourcefn dealloc(&mut self, ppn: PhysPageNum)
Auto Trait Implementations
impl RefUnwindSafe for StackFrameAllocator
impl Send for StackFrameAllocator
impl Sync for StackFrameAllocator
impl Unpin for StackFrameAllocator
impl UnwindSafe for StackFrameAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
an implementation for frame allocator
+Fields§
§current: usize
§end: usize
§recycled: Vec<usize>
Implementations§
source§impl StackFrameAllocator
sourcepub fn init(&mut self, l: PhysPageNum, r: PhysPageNum)
Trait Implementations§
source§impl FrameAllocator for StackFrameAllocator
Auto Trait Implementations§
§impl RefUnwindSafe for StackFrameAllocator
§impl Send for StackFrameAllocator
§impl Sync for StackFrameAllocator
§impl Unpin for StackFrameAllocator
§impl UnwindSafe for StackFrameAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/trait.FrameAllocator.html b/ch5/os/mm/frame_allocator/trait.FrameAllocator.html
index 3df2abda..28041a23 100644
--- a/ch5/os/mm/frame_allocator/trait.FrameAllocator.html
+++ b/ch5/os/mm/frame_allocator/trait.FrameAllocator.html
@@ -1,5 +1,6 @@
-FrameAllocator in os::mm::frame_allocator - Rust Trait os::mm::frame_allocator::FrameAllocator
source · [−]trait FrameAllocator {
- fn new() -> Self;
- fn alloc(&mut self) -> Option<PhysPageNum>;
- fn dealloc(&mut self, ppn: PhysPageNum);
-}
Required Methods
fn alloc(&mut self) -> Option<PhysPageNum>
fn dealloc(&mut self, ppn: PhysPageNum)
Implementors
sourceimpl FrameAllocator for StackFrameAllocator
\ No newline at end of file
+FrameAllocator in os::mm::frame_allocator - Rust Trait os::mm::frame_allocator::FrameAllocator
source · trait FrameAllocator {
+ // Required methods
+ fn new() -> Self;
+ fn alloc(&mut self) -> Option<PhysPageNum>;
+ fn dealloc(&mut self, ppn: PhysPageNum);
+}
Required Methods§
sourcefn new() -> Self
sourcefn alloc(&mut self) -> Option<PhysPageNum>
sourcefn dealloc(&mut self, ppn: PhysPageNum)
Implementors§
source§impl FrameAllocator for StackFrameAllocator
\ No newline at end of file
diff --git a/ch5/os/mm/frame_allocator/type.FrameAllocatorImpl.html b/ch5/os/mm/frame_allocator/type.FrameAllocatorImpl.html
index 2a27d08a..235bf775 100644
--- a/ch5/os/mm/frame_allocator/type.FrameAllocatorImpl.html
+++ b/ch5/os/mm/frame_allocator/type.FrameAllocatorImpl.html
@@ -1 +1,5 @@
-FrameAllocatorImpl in os::mm::frame_allocator - Rust Type Definition os::mm::frame_allocator::FrameAllocatorImpl
source · [−]type FrameAllocatorImpl = StackFrameAllocator;
\ No newline at end of file
+FrameAllocatorImpl in os::mm::frame_allocator - Rust Type Alias os::mm::frame_allocator::FrameAllocatorImpl
source · type FrameAllocatorImpl = StackFrameAllocator;
Aliased Type§
struct FrameAllocatorImpl {
+ current: usize,
+ end: usize,
+ recycled: Vec<usize, Global>,
+}
Fields§
§current: usize
§end: usize
§recycled: Vec<usize, Global>
Implementations§
source§impl StackFrameAllocator
sourcepub fn init(&mut self, l: PhysPageNum, r: PhysPageNum)
Trait Implementations§
source§impl FrameAllocator for StackFrameAllocator
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/fn.handle_alloc_error.html b/ch5/os/mm/heap_allocator/fn.handle_alloc_error.html
index 8e13a4d5..6bb35dfb 100644
--- a/ch5/os/mm/heap_allocator/fn.handle_alloc_error.html
+++ b/ch5/os/mm/heap_allocator/fn.handle_alloc_error.html
@@ -1,2 +1,2 @@
-handle_alloc_error in os::mm::heap_allocator - Rust Function os::mm::heap_allocator::handle_alloc_error
source · [−]Expand description
panic when heap allocation error occurs
-
\ No newline at end of file
+handle_alloc_error in os::mm::heap_allocator - Rust Function os::mm::heap_allocator::handle_alloc_error
source · pub fn handle_alloc_error(layout: Layout) -> !
Expand description
panic when heap allocation error occurs
+
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/fn.heap_test.html b/ch5/os/mm/heap_allocator/fn.heap_test.html
index 87a16d46..5de05955 100644
--- a/ch5/os/mm/heap_allocator/fn.heap_test.html
+++ b/ch5/os/mm/heap_allocator/fn.heap_test.html
@@ -1 +1 @@
-heap_test in os::mm::heap_allocator - Rust
\ No newline at end of file
+heap_test in os::mm::heap_allocator - Rust Function os::mm::heap_allocator::heap_test
source · pub fn heap_test()
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/fn.init_heap.html b/ch5/os/mm/heap_allocator/fn.init_heap.html
index 9983266d..03da3c6e 100644
--- a/ch5/os/mm/heap_allocator/fn.init_heap.html
+++ b/ch5/os/mm/heap_allocator/fn.init_heap.html
@@ -1,2 +1,2 @@
-init_heap in os::mm::heap_allocator - Rust
\ No newline at end of file
+init_heap in os::mm::heap_allocator - Rust Function os::mm::heap_allocator::init_heap
source · pub fn init_heap()
Expand description
initiate heap allocator
+
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/index.html b/ch5/os/mm/heap_allocator/index.html
index 05472122..e99493c8 100644
--- a/ch5/os/mm/heap_allocator/index.html
+++ b/ch5/os/mm/heap_allocator/index.html
@@ -1,6 +1,2 @@
-os::mm::heap_allocator - Rust
\ No newline at end of file
+os::mm::heap_allocator - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/sidebar-items.js b/ch5/os/mm/heap_allocator/sidebar-items.js
index 7d2480db..d5956da4 100644
--- a/ch5/os/mm/heap_allocator/sidebar-items.js
+++ b/ch5/os/mm/heap_allocator/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["handle_alloc_error","panic when heap allocation error occurs"],["heap_test",""],["init_heap","initiate heap allocator"]],"static":[["HEAP_ALLOCATOR","heap allocator instance"],["HEAP_SPACE","heap space ([u8; KERNEL_HEAP_SIZE])"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["handle_alloc_error","heap_test","init_heap"],"static":["HEAP_ALLOCATOR","HEAP_SPACE"]};
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/static.HEAP_ALLOCATOR.html b/ch5/os/mm/heap_allocator/static.HEAP_ALLOCATOR.html
index f91d542d..3761e118 100644
--- a/ch5/os/mm/heap_allocator/static.HEAP_ALLOCATOR.html
+++ b/ch5/os/mm/heap_allocator/static.HEAP_ALLOCATOR.html
@@ -1,2 +1,2 @@
-HEAP_ALLOCATOR in os::mm::heap_allocator - Rust Static os::mm::heap_allocator::HEAP_ALLOCATOR
source · [−]static HEAP_ALLOCATOR: LockedHeap
Expand description
heap allocator instance
-
\ No newline at end of file
+HEAP_ALLOCATOR in os::mm::heap_allocator - Rust Static os::mm::heap_allocator::HEAP_ALLOCATOR
source · static HEAP_ALLOCATOR: LockedHeap
Expand description
heap allocator instance
+
\ No newline at end of file
diff --git a/ch5/os/mm/heap_allocator/static.HEAP_SPACE.html b/ch5/os/mm/heap_allocator/static.HEAP_SPACE.html
index c4b9180f..1d6274fc 100644
--- a/ch5/os/mm/heap_allocator/static.HEAP_SPACE.html
+++ b/ch5/os/mm/heap_allocator/static.HEAP_SPACE.html
@@ -1,2 +1,2 @@
-HEAP_SPACE in os::mm::heap_allocator - Rust Static os::mm::heap_allocator::HEAP_SPACE
source · [−]static mut HEAP_SPACE: [u8; 2097152]
Expand description
heap space ([u8; KERNEL_HEAP_SIZE])
-
\ No newline at end of file
+HEAP_SPACE in os::mm::heap_allocator - Rust Static os::mm::heap_allocator::HEAP_SPACE
source · static mut HEAP_SPACE: [u8; 2097152]
Expand description
heap space ([u8; KERNEL_HEAP_SIZE])
+
\ No newline at end of file
diff --git a/ch5/os/mm/index.html b/ch5/os/mm/index.html
index 6b507979..8ea05843 100644
--- a/ch5/os/mm/index.html
+++ b/ch5/os/mm/index.html
@@ -1,27 +1,7 @@
-os::mm - Rust Expand description
Memory management implementation
+os::mm - Rust Expand description
Memory management implementation
SV39 page-based virtual-memory architecture for RV64 systems, and
everything about memory management, like frame allocator, page table,
map area and memory set, is implemented here.
Every task or process has a memory_set to control its virtual memory.
-Modules
address 🔒 Implementation of physical and virtual address and page number.
-Implementation of FrameAllocator
which
-controls all the frames in the operating system.
-The global allocator
-Implementation of PageTableEntry
and PageTable
.
-Structs
manage a frame which has the same lifecycle as the tracker
-a memory set instance through lazy_static! managing kernel space
-map permission corresponding to that in pte: R W X U
-memory set structure, controls virtual-memory space
-page table entry structure
-physical address
-physical page number
-virtual address
-virtual page number
-Functions
allocate a frame
-initiate heap allocator, frame allocator and kernel space
-Check PageTable running correctly
-translate a pointer to a mutable u8 Vec through page table
-translate a generic through page table and return a mutable reference
-translate a pointer to a mutable u8 Vec end with \0
through page table to a String
-
\ No newline at end of file
+Re-exports
pub use memory_set::KERNEL_SPACE;
pub use memory_set::KERNEL_SPACE;
Modules
- address 🔒 Implementation of physical and virtual address and page number.
- Implementation of
FrameAllocator
which
+controls all the frames in the operating system. - The global allocator
- Implementation of
PageTableEntry
and PageTable
.
Structs
- manage a frame which has the same lifecycle as the tracker
- a memory set instance through lazy_static! managing kernel space
- map permission corresponding to that in pte:
R W X U
- memory set structure, controls virtual-memory space
- page table entry structure
- physical address
- physical page number
- virtual address
- virtual page number
Functions
- allocate a frame
- initiate heap allocator, frame allocator and kernel space
- Check PageTable running correctly
- translate a pointer to a mutable u8 Vec through page table
- translate a generic through page table and return a mutable reference
- translate a pointer to a mutable u8 Vec end with
\0
through page table to a String
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/enum.MapType.html b/ch5/os/mm/memory_set/enum.MapType.html
index cba20314..31259549 100644
--- a/ch5/os/mm/memory_set/enum.MapType.html
+++ b/ch5/os/mm/memory_set/enum.MapType.html
@@ -1,25 +1,18 @@
-MapType in os::mm::memory_set - Rust pub enum MapType {
+MapType in os::mm::memory_set - Rust Enum os::mm::memory_set::MapType
source · pub enum MapType {
Identical,
Framed,
-}
Expand description
map type for memory set: identical or framed
-Variants
Identical
Framed
Trait Implementations
sourceimpl Copy for MapType
sourceimpl StructuralPartialEq for MapType
Auto Trait Implementations
impl RefUnwindSafe for MapType
impl Send for MapType
impl Sync for MapType
impl Unpin for MapType
impl UnwindSafe for MapType
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
map type for memory set: identical or framed
+Variants§
Trait Implementations§
source§impl PartialEq<MapType> for MapType
source§impl Copy for MapType
source§impl StructuralPartialEq for MapType
Auto Trait Implementations§
§impl RefUnwindSafe for MapType
§impl Send for MapType
§impl Sync for MapType
§impl Unpin for MapType
§impl UnwindSafe for MapType
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.ebss.html b/ch5/os/mm/memory_set/fn.ebss.html
index c9568848..2b13c3d5 100644
--- a/ch5/os/mm/memory_set/fn.ebss.html
+++ b/ch5/os/mm/memory_set/fn.ebss.html
@@ -1 +1 @@
-ebss in os::mm::memory_set - Rust
\ No newline at end of file
+ebss in os::mm::memory_set - Rust Function os::mm::memory_set::ebss
source · unsafe extern "C" fn ebss()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.edata.html b/ch5/os/mm/memory_set/fn.edata.html
index 9ccf48d0..6692613e 100644
--- a/ch5/os/mm/memory_set/fn.edata.html
+++ b/ch5/os/mm/memory_set/fn.edata.html
@@ -1 +1 @@
-edata in os::mm::memory_set - Rust
\ No newline at end of file
+edata in os::mm::memory_set - Rust Function os::mm::memory_set::edata
source · unsafe extern "C" fn edata()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.ekernel.html b/ch5/os/mm/memory_set/fn.ekernel.html
index c8d8df92..776a8212 100644
--- a/ch5/os/mm/memory_set/fn.ekernel.html
+++ b/ch5/os/mm/memory_set/fn.ekernel.html
@@ -1 +1 @@
-ekernel in os::mm::memory_set - Rust
\ No newline at end of file
+ekernel in os::mm::memory_set - Rust Function os::mm::memory_set::ekernel
source · unsafe extern "C" fn ekernel()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.erodata.html b/ch5/os/mm/memory_set/fn.erodata.html
index 8034b1eb..59b2a302 100644
--- a/ch5/os/mm/memory_set/fn.erodata.html
+++ b/ch5/os/mm/memory_set/fn.erodata.html
@@ -1 +1 @@
-erodata in os::mm::memory_set - Rust
\ No newline at end of file
+erodata in os::mm::memory_set - Rust Function os::mm::memory_set::erodata
source · unsafe extern "C" fn erodata()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.etext.html b/ch5/os/mm/memory_set/fn.etext.html
index 36471060..ea098077 100644
--- a/ch5/os/mm/memory_set/fn.etext.html
+++ b/ch5/os/mm/memory_set/fn.etext.html
@@ -1 +1 @@
-etext in os::mm::memory_set - Rust
\ No newline at end of file
+etext in os::mm::memory_set - Rust Function os::mm::memory_set::etext
source · unsafe extern "C" fn etext()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.remap_test.html b/ch5/os/mm/memory_set/fn.remap_test.html
index c2104c88..eb82d41d 100644
--- a/ch5/os/mm/memory_set/fn.remap_test.html
+++ b/ch5/os/mm/memory_set/fn.remap_test.html
@@ -1,2 +1,2 @@
-remap_test in os::mm::memory_set - Rust Function os::mm::memory_set::remap_test
source · [−]pub fn remap_test()
Expand description
Check PageTable running correctly
-
\ No newline at end of file
+remap_test in os::mm::memory_set - Rust Function os::mm::memory_set::remap_test
source · pub fn remap_test()
Expand description
Check PageTable running correctly
+
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.sbss_with_stack.html b/ch5/os/mm/memory_set/fn.sbss_with_stack.html
index ff32cd95..aa9603cd 100644
--- a/ch5/os/mm/memory_set/fn.sbss_with_stack.html
+++ b/ch5/os/mm/memory_set/fn.sbss_with_stack.html
@@ -1 +1 @@
-sbss_with_stack in os::mm::memory_set - Rust Function os::mm::memory_set::sbss_with_stack
source · [−]unsafe extern "C" fn sbss_with_stack()
\ No newline at end of file
+sbss_with_stack in os::mm::memory_set - Rust Function os::mm::memory_set::sbss_with_stack
source · unsafe extern "C" fn sbss_with_stack()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.sdata.html b/ch5/os/mm/memory_set/fn.sdata.html
index e7af7f15..f57910fc 100644
--- a/ch5/os/mm/memory_set/fn.sdata.html
+++ b/ch5/os/mm/memory_set/fn.sdata.html
@@ -1 +1 @@
-sdata in os::mm::memory_set - Rust
\ No newline at end of file
+sdata in os::mm::memory_set - Rust Function os::mm::memory_set::sdata
source · unsafe extern "C" fn sdata()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.srodata.html b/ch5/os/mm/memory_set/fn.srodata.html
index eed5ba21..04b75488 100644
--- a/ch5/os/mm/memory_set/fn.srodata.html
+++ b/ch5/os/mm/memory_set/fn.srodata.html
@@ -1 +1 @@
-srodata in os::mm::memory_set - Rust
\ No newline at end of file
+srodata in os::mm::memory_set - Rust Function os::mm::memory_set::srodata
source · unsafe extern "C" fn srodata()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.stext.html b/ch5/os/mm/memory_set/fn.stext.html
index 088ece06..7d72ec3a 100644
--- a/ch5/os/mm/memory_set/fn.stext.html
+++ b/ch5/os/mm/memory_set/fn.stext.html
@@ -1 +1 @@
-stext in os::mm::memory_set - Rust
\ No newline at end of file
+stext in os::mm::memory_set - Rust Function os::mm::memory_set::stext
source · unsafe extern "C" fn stext()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/fn.strampoline.html b/ch5/os/mm/memory_set/fn.strampoline.html
index b76b16d9..fb5dd69d 100644
--- a/ch5/os/mm/memory_set/fn.strampoline.html
+++ b/ch5/os/mm/memory_set/fn.strampoline.html
@@ -1 +1 @@
-strampoline in os::mm::memory_set - Rust Function os::mm::memory_set::strampoline
source · [−]unsafe extern "C" fn strampoline()
\ No newline at end of file
+strampoline in os::mm::memory_set - Rust Function os::mm::memory_set::strampoline
source · unsafe extern "C" fn strampoline()
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/index.html b/ch5/os/mm/memory_set/index.html
index ec3579a6..2f7d218a 100644
--- a/ch5/os/mm/memory_set/index.html
+++ b/ch5/os/mm/memory_set/index.html
@@ -1,8 +1,2 @@
-os::mm::memory_set - Rust Module os::mm::memory_set
source · [−]Structs
a memory set instance through lazy_static! managing kernel space
-map area structure, controls a contiguous piece of virtual memory
-map permission corresponding to that in pte: R W X U
-memory set structure, controls virtual-memory space
-Enums
map type for memory set: identical or framed
-Functions
\ No newline at end of file
+os::mm::memory_set - Rust Module os::mm::memory_set
source · Structs
- a memory set instance through lazy_static! managing kernel space
- map area structure, controls a contiguous piece of virtual memory
- map permission corresponding to that in pte:
R W X U
- memory set structure, controls virtual-memory space
Enums
- map type for memory set: identical or framed
Functions
- ebss 🔒 ⚠
- edata 🔒 ⚠
- ekernel 🔒 ⚠
- erodata 🔒 ⚠
- etext 🔒 ⚠
- Check PageTable running correctly
- sbss_with_stack 🔒 ⚠
- sdata 🔒 ⚠
- srodata 🔒 ⚠
- stext 🔒 ⚠
- strampoline 🔒 ⚠
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/sidebar-items.js b/ch5/os/mm/memory_set/sidebar-items.js
index 8953e712..2622ef9c 100644
--- a/ch5/os/mm/memory_set/sidebar-items.js
+++ b/ch5/os/mm/memory_set/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"enum":[["MapType","map type for memory set: identical or framed"]],"fn":[["ebss",""],["edata",""],["ekernel",""],["erodata",""],["etext",""],["remap_test","Check PageTable running correctly"],["sbss_with_stack",""],["sdata",""],["srodata",""],["stext",""],["strampoline",""]],"struct":[["KERNEL_SPACE","a memory set instance through lazy_static! managing kernel space"],["MapArea","map area structure, controls a contiguous piece of virtual memory"],["MapPermission","map permission corresponding to that in pte: `R W X U`"],["MemorySet","memory set structure, controls virtual-memory space"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"enum":["MapType"],"fn":["ebss","edata","ekernel","erodata","etext","remap_test","sbss_with_stack","sdata","srodata","stext","strampoline"],"struct":["KERNEL_SPACE","MapArea","MapPermission","MemorySet"]};
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/struct.KERNEL_SPACE.html b/ch5/os/mm/memory_set/struct.KERNEL_SPACE.html
index 62dde97b..df99208f 100644
--- a/ch5/os/mm/memory_set/struct.KERNEL_SPACE.html
+++ b/ch5/os/mm/memory_set/struct.KERNEL_SPACE.html
@@ -1,17 +1,14 @@
-KERNEL_SPACE in os::mm::memory_set - Rust Struct os::mm::memory_set::KERNEL_SPACE
source · [−]pub struct KERNEL_SPACE {
+KERNEL_SPACE in os::mm::memory_set - Rust Struct os::mm::memory_set::KERNEL_SPACE
source · pub struct KERNEL_SPACE {
__private_field: (),
-}
Expand description
a memory set instance through lazy_static! managing kernel space
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for KERNEL_SPACE
type Target = Arc<UPSafeCell<MemorySet>>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<UPSafeCell<MemorySet>>
Dereferences the value.
-sourceimpl LazyStatic for KERNEL_SPACE
Auto Trait Implementations
impl RefUnwindSafe for KERNEL_SPACE
impl Send for KERNEL_SPACE
impl Sync for KERNEL_SPACE
impl Unpin for KERNEL_SPACE
impl UnwindSafe for KERNEL_SPACE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a memory set instance through lazy_static! managing kernel space
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for KERNEL_SPACE
source§impl LazyStatic for KERNEL_SPACE
Auto Trait Implementations§
§impl RefUnwindSafe for KERNEL_SPACE
§impl Send for KERNEL_SPACE
§impl Sync for KERNEL_SPACE
§impl Unpin for KERNEL_SPACE
§impl UnwindSafe for KERNEL_SPACE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/struct.MapArea.html b/ch5/os/mm/memory_set/struct.MapArea.html
index f295f76d..25befb8c 100644
--- a/ch5/os/mm/memory_set/struct.MapArea.html
+++ b/ch5/os/mm/memory_set/struct.MapArea.html
@@ -1,20 +1,24 @@
-MapArea in os::mm::memory_set - Rust pub struct MapArea {
+MapArea in os::mm::memory_set - Rust Struct os::mm::memory_set::MapArea
source · pub struct MapArea {
vpn_range: SimpleRange<VirtPageNum>,
data_frames: BTreeMap<VirtPageNum, FrameTracker>,
map_type: MapType,
map_perm: MapPermission,
-}
Expand description
map area structure, controls a contiguous piece of virtual memory
-Fields
vpn_range: SimpleRange<VirtPageNum>
data_frames: BTreeMap<VirtPageNum, FrameTracker>
map_type: MapType
map_perm: MapPermission
Implementations
sourceimpl MapArea
sourcepub fn new(
start_va: VirtAddr,
end_va: VirtAddr,
map_type: MapType,
map_perm: MapPermission
) -> Self
sourcepub fn from_another(another: &Self) -> Self
sourcepub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn map(&mut self, page_table: &mut PageTable)
sourcepub fn unmap(&mut self, page_table: &mut PageTable)
sourcepub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8])
data: start-aligned but maybe with shorter length
+}Expand description
map area structure, controls a contiguous piece of virtual memory
+
Fields§
§vpn_range: SimpleRange<VirtPageNum>
§data_frames: BTreeMap<VirtPageNum, FrameTracker>
§map_type: MapType
§map_perm: MapPermission
Implementations§
source§impl MapArea
sourcepub fn new(
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ map_type: MapType,
+ map_perm: MapPermission
+) -> Self
sourcepub fn from_another(another: &Self) -> Self
sourcepub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn map(&mut self, page_table: &mut PageTable)
sourcepub fn unmap(&mut self, page_table: &mut PageTable)
Auto Trait Implementations
impl RefUnwindSafe for MapArea
impl Send for MapArea
impl Sync for MapArea
impl Unpin for MapArea
impl UnwindSafe for MapArea
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Auto Trait Implementations§
§impl RefUnwindSafe for MapArea
§impl Send for MapArea
§impl Sync for MapArea
§impl Unpin for MapArea
§impl UnwindSafe for MapArea
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/struct.MapPermission.html b/ch5/os/mm/memory_set/struct.MapPermission.html
index 9cf4e2d5..d4c434da 100644
--- a/ch5/os/mm/memory_set/struct.MapPermission.html
+++ b/ch5/os/mm/memory_set/struct.MapPermission.html
@@ -1,18 +1,18 @@
-MapPermission in os::mm::memory_set - Rust Struct os::mm::memory_set::MapPermission
source · [−]pub struct MapPermission {
+MapPermission in os::mm::memory_set - Rust Struct os::mm::memory_set::MapPermission
source · pub struct MapPermission {
bits: u8,
-}
Expand description
map permission corresponding to that in pte: R W X U
-Fields
bits: u8
Implementations
sourceimpl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
map permission corresponding to that in pte: R W X U
+
Fields§
§bits: u8
Implementations§
source§impl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -20,35 +20,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -56,66 +56,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl Binary for MapPermission
sourceimpl BitAnd<MapPermission> for MapPermission
type Output = MapPermission
The resulting type after applying the &
operator.
-sourceimpl BitAndAssign<MapPermission> for MapPermission
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOr<MapPermission> for MapPermission
sourcefn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
-type Output = MapPermission
The resulting type after applying the |
operator.
-sourceimpl BitOrAssign<MapPermission> for MapPermission
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXor<MapPermission> for MapPermission
sourcefn bitxor(self, other: Self) -> Self
Returns the left flags, but with all the right flags toggled.
-type Output = MapPermission
The resulting type after applying the ^
operator.
-sourceimpl BitXorAssign<MapPermission> for MapPermission
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Clone for MapPermission
sourcefn clone(&self) -> MapPermission
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for MapPermission
sourceimpl Extend<MapPermission> for MapPermission
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<MapPermission> for MapPermission
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Hash for MapPermission
sourceimpl LowerHex for MapPermission
sourceimpl Not for MapPermission
type Output = MapPermission
The resulting type after applying the !
operator.
-sourceimpl Octal for MapPermission
sourceimpl Ord for MapPermission
sourcefn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<MapPermission> for MapPermission
sourcefn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &MapPermission) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<MapPermission> for MapPermission
sourcefn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Sub<MapPermission> for MapPermission
type Output = MapPermission
The resulting type after applying the -
operator.
-sourceimpl SubAssign<MapPermission> for MapPermission
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl UpperHex for MapPermission
sourceimpl Copy for MapPermission
sourceimpl Eq for MapPermission
sourceimpl StructuralEq for MapPermission
sourceimpl StructuralPartialEq for MapPermission
Auto Trait Implementations
impl RefUnwindSafe for MapPermission
impl Send for MapPermission
impl Sync for MapPermission
impl Unpin for MapPermission
impl UnwindSafe for MapPermission
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl Binary for MapPermission
source§impl BitAnd<MapPermission> for MapPermission
source§impl BitAndAssign<MapPermission> for MapPermission
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOr<MapPermission> for MapPermission
source§fn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
+§type Output = MapPermission
The resulting type after applying the |
operator.source§impl BitOrAssign<MapPermission> for MapPermission
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXor<MapPermission> for MapPermission
source§impl BitXorAssign<MapPermission> for MapPermission
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Clone for MapPermission
source§fn clone(&self) -> MapPermission
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for MapPermission
source§impl Extend<MapPermission> for MapPermission
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<MapPermission> for MapPermission
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Hash for MapPermission
source§impl LowerHex for MapPermission
source§impl Not for MapPermission
source§impl Octal for MapPermission
source§impl Ord for MapPermission
source§fn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<MapPermission> for MapPermission
source§fn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<MapPermission> for MapPermission
source§fn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Sub<MapPermission> for MapPermission
source§impl SubAssign<MapPermission> for MapPermission
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl UpperHex for MapPermission
source§impl Copy for MapPermission
source§impl Eq for MapPermission
source§impl StructuralEq for MapPermission
source§impl StructuralPartialEq for MapPermission
Auto Trait Implementations§
§impl RefUnwindSafe for MapPermission
§impl Send for MapPermission
§impl Sync for MapPermission
§impl Unpin for MapPermission
§impl UnwindSafe for MapPermission
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/memory_set/struct.MemorySet.html b/ch5/os/mm/memory_set/struct.MemorySet.html
index 8da46fdf..5afb1bb3 100644
--- a/ch5/os/mm/memory_set/struct.MemorySet.html
+++ b/ch5/os/mm/memory_set/struct.MemorySet.html
@@ -1,28 +1,32 @@
-MemorySet in os::mm::memory_set - Rust pub struct MemorySet {
+MemorySet in os::mm::memory_set - Rust Struct os::mm::memory_set::MemorySet
source · pub struct MemorySet {
page_table: PageTable,
areas: Vec<MapArea>,
-}
Expand description
memory set structure, controls virtual-memory space
-Fields
page_table: PageTable
areas: Vec<MapArea>
Implementations
sourceimpl MemorySet
sourcepub fn insert_framed_area(
&mut self,
start_va: VirtAddr,
end_va: VirtAddr,
permission: MapPermission
)
Assume that no conflicts.
-sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
-sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
-sourcepub fn new_kernel() -> Self
Without kernel stacks.
-sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
+}Expand description
memory set structure, controls virtual-memory space
+
Fields§
§page_table: PageTable
§areas: Vec<MapArea>
Implementations§
source§impl MemorySet
sourcepub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission
+)
Assume that no conflicts.
+sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
+sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
+sourcepub fn new_kernel() -> Self
Without kernel stacks.
+sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
also returns user_sp and entry point.
-sourcepub fn from_existed_user(user_space: &Self) -> Self
Clone a same MemorySet
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
-sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
-Auto Trait Implementations
impl RefUnwindSafe for MemorySet
impl Send for MemorySet
impl Sync for MemorySet
impl Unpin for MemorySet
impl UnwindSafe for MemorySet
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
sourcepub fn from_existed_user(user_space: &Self) -> Self
Clone a same MemorySet
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
+sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
+Auto Trait Implementations§
§impl RefUnwindSafe for MemorySet
§impl Send for MemorySet
§impl Sync for MemorySet
§impl Unpin for MemorySet
§impl UnwindSafe for MemorySet
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/fn.translated_byte_buffer.html b/ch5/os/mm/page_table/fn.translated_byte_buffer.html
index cb221bab..11709ad6 100644
--- a/ch5/os/mm/page_table/fn.translated_byte_buffer.html
+++ b/ch5/os/mm/page_table/fn.translated_byte_buffer.html
@@ -1,2 +1,6 @@
-translated_byte_buffer in os::mm::page_table - Rust
\ No newline at end of file
+translated_byte_buffer in os::mm::page_table - Rust
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/fn.translated_refmut.html b/ch5/os/mm/page_table/fn.translated_refmut.html
index c6d3792c..c1885f1b 100644
--- a/ch5/os/mm/page_table/fn.translated_refmut.html
+++ b/ch5/os/mm/page_table/fn.translated_refmut.html
@@ -1,2 +1,2 @@
-translated_refmut in os::mm::page_table - Rust Function os::mm::page_table::translated_refmut
source · [−]pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Expand description
translate a generic through page table and return a mutable reference
-
\ No newline at end of file
+translated_refmut in os::mm::page_table - Rust Function os::mm::page_table::translated_refmut
source · pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Expand description
translate a generic through page table and return a mutable reference
+
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/fn.translated_str.html b/ch5/os/mm/page_table/fn.translated_str.html
index 20a57bc0..76799d94 100644
--- a/ch5/os/mm/page_table/fn.translated_str.html
+++ b/ch5/os/mm/page_table/fn.translated_str.html
@@ -1,2 +1,2 @@
-translated_str in os::mm::page_table - Rust Function os::mm::page_table::translated_str
source · [−]Expand description
translate a pointer to a mutable u8 Vec end with \0
through page table to a String
-
\ No newline at end of file
+translated_str in os::mm::page_table - Rust Function os::mm::page_table::translated_str
source · pub fn translated_str(token: usize, ptr: *const u8) -> String
Expand description
translate a pointer to a mutable u8 Vec end with \0
through page table to a String
+
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/index.html b/ch5/os/mm/page_table/index.html
index 50cbaa16..618aab4c 100644
--- a/ch5/os/mm/page_table/index.html
+++ b/ch5/os/mm/page_table/index.html
@@ -1,6 +1,2 @@
-os::mm::page_table - Rust Module os::mm::page_table
source · [−]Expand description
Implementation of PageTableEntry
and PageTable
.
-Structs
Functions
translate a pointer to a mutable u8 Vec through page table
-translate a generic through page table and return a mutable reference
-translate a pointer to a mutable u8 Vec end with \0
through page table to a String
-
\ No newline at end of file
+os::mm::page_table - Rust Module os::mm::page_table
source · Expand description
Implementation of PageTableEntry
and PageTable
.
+Structs
- page table entry structure
Functions
- translate a pointer to a mutable u8 Vec through page table
- translate a generic through page table and return a mutable reference
- translate a pointer to a mutable u8 Vec end with
\0
through page table to a String
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/sidebar-items.js b/ch5/os/mm/page_table/sidebar-items.js
index 6e279f3c..8f39db9b 100644
--- a/ch5/os/mm/page_table/sidebar-items.js
+++ b/ch5/os/mm/page_table/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["translated_byte_buffer","translate a pointer to a mutable u8 Vec through page table"],["translated_refmut","translate a generic through page table and return a mutable reference"],["translated_str","translate a pointer to a mutable u8 Vec end with `\\0` through page table to a `String`"]],"struct":[["PTEFlags",""],["PageTable",""],["PageTableEntry","page table entry structure"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["translated_byte_buffer","translated_refmut","translated_str"],"struct":["PTEFlags","PageTable","PageTableEntry"]};
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/struct.PTEFlags.html b/ch5/os/mm/page_table/struct.PTEFlags.html
index 2825b544..4e6a2188 100644
--- a/ch5/os/mm/page_table/struct.PTEFlags.html
+++ b/ch5/os/mm/page_table/struct.PTEFlags.html
@@ -1,13 +1,13 @@
-PTEFlags in os::mm::page_table - Rust pub struct PTEFlags {
+PTEFlags in os::mm::page_table - Rust Fields
bits: u8
Implementations
sourceimpl PTEFlags
sourcepub const V: Self = _
sourcepub const R: Self = _
sourcepub const W: Self = _
sourcepub const X: Self = _
sourcepub const U: Self = _
sourcepub const G: Self = _
sourcepub const A: Self = _
sourcepub const D: Self = _
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}
Fields§
§bits: u8
Implementations§
source§impl PTEFlags
sourcepub const V: Self = _
sourcepub const R: Self = _
sourcepub const W: Self = _
sourcepub const X: Self = _
sourcepub const U: Self = _
sourcepub const G: Self = _
sourcepub const A: Self = _
sourcepub const D: Self = _
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -15,35 +15,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -51,66 +51,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl BitAndAssign<PTEFlags> for PTEFlags
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOrAssign<PTEFlags> for PTEFlags
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXorAssign<PTEFlags> for PTEFlags
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Extend<PTEFlags> for PTEFlags
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<PTEFlags> for PTEFlags
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Ord for PTEFlags
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialOrd<PTEFlags> for PTEFlags
sourcefn partial_cmp(&self, other: &PTEFlags) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl SubAssign<PTEFlags> for PTEFlags
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl Copy for PTEFlags
sourceimpl Eq for PTEFlags
sourceimpl StructuralEq for PTEFlags
sourceimpl StructuralPartialEq for PTEFlags
Auto Trait Implementations
impl RefUnwindSafe for PTEFlags
impl Send for PTEFlags
impl Sync for PTEFlags
impl Unpin for PTEFlags
impl UnwindSafe for PTEFlags
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl BitAndAssign<PTEFlags> for PTEFlags
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOrAssign<PTEFlags> for PTEFlags
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXorAssign<PTEFlags> for PTEFlags
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Extend<PTEFlags> for PTEFlags
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<PTEFlags> for PTEFlags
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Ord for PTEFlags
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PTEFlags> for PTEFlags
source§impl PartialOrd<PTEFlags> for PTEFlags
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl SubAssign<PTEFlags> for PTEFlags
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl Copy for PTEFlags
source§impl Eq for PTEFlags
source§impl StructuralEq for PTEFlags
source§impl StructuralPartialEq for PTEFlags
Auto Trait Implementations§
§impl RefUnwindSafe for PTEFlags
§impl Send for PTEFlags
§impl Sync for PTEFlags
§impl Unpin for PTEFlags
§impl UnwindSafe for PTEFlags
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/struct.PageTable.html b/ch5/os/mm/page_table/struct.PageTable.html
index bc522631..a56c0672 100644
--- a/ch5/os/mm/page_table/struct.PageTable.html
+++ b/ch5/os/mm/page_table/struct.PageTable.html
@@ -1,17 +1,16 @@
-PageTable in os::mm::page_table - Rust pub struct PageTable {
+PageTable in os::mm::page_table - Rust Struct os::mm::page_table::PageTable
source · pub struct PageTable {
root_ppn: PhysPageNum,
frames: Vec<FrameTracker>,
-}
Fields
root_ppn: PhysPageNum
frames: Vec<FrameTracker>
Implementations
sourceimpl PageTable
Assume that it won’t oom when creating/mapping.
-sourcepub fn new() -> Self
sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
-sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
sourcepub fn unmap(&mut self, vpn: VirtPageNum)
sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
sourcepub fn token(&self) -> usize
Auto Trait Implementations
impl RefUnwindSafe for PageTable
impl Send for PageTable
impl Sync for PageTable
impl Unpin for PageTable
impl UnwindSafe for PageTable
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§root_ppn: PhysPageNum
§frames: Vec<FrameTracker>
Implementations§
source§impl PageTable
Assume that it won’t oom when creating/mapping.
+sourcepub fn new() -> Self
sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
+sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
sourcepub fn unmap(&mut self, vpn: VirtPageNum)
sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
sourcepub fn token(&self) -> usize
Auto Trait Implementations§
§impl RefUnwindSafe for PageTable
§impl Send for PageTable
§impl Sync for PageTable
§impl Unpin for PageTable
§impl UnwindSafe for PageTable
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/page_table/struct.PageTableEntry.html b/ch5/os/mm/page_table/struct.PageTableEntry.html
index 848a76cb..dae19078 100644
--- a/ch5/os/mm/page_table/struct.PageTableEntry.html
+++ b/ch5/os/mm/page_table/struct.PageTableEntry.html
@@ -1,29 +1,24 @@
-PageTableEntry in os::mm::page_table - Rust Struct os::mm::page_table::PageTableEntry
source · [−]#[repr(C)]pub struct PageTableEntry {
+PageTableEntry in os::mm::page_table - Rust Struct os::mm::page_table::PageTableEntry
source · #[repr(C)]pub struct PageTableEntry {
pub bits: usize,
-}
Expand description
page table entry structure
-Fields
bits: usize
PTE
-Implementations
sourceimpl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
-sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
-sourcepub fn executable(&self) -> bool
Check PTE executable
-Trait Implementations
sourceimpl Clone for PageTableEntry
sourcefn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Copy for PageTableEntry
Auto Trait Implementations
impl RefUnwindSafe for PageTableEntry
impl Send for PageTableEntry
impl Sync for PageTableEntry
impl Unpin for PageTableEntry
impl UnwindSafe for PageTableEntry
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
page table entry structure
+Fields§
§bits: usize
PTE
+Implementations§
source§impl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
+sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
+sourcepub fn executable(&self) -> bool
Check PTE executable
+Trait Implementations§
source§impl Clone for PageTableEntry
source§fn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Copy for PageTableEntry
Auto Trait Implementations§
§impl RefUnwindSafe for PageTableEntry
§impl Send for PageTableEntry
§impl Sync for PageTableEntry
§impl Unpin for PageTableEntry
§impl UnwindSafe for PageTableEntry
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/sidebar-items.js b/ch5/os/mm/sidebar-items.js
index b8b598cd..2b56b532 100644
--- a/ch5/os/mm/sidebar-items.js
+++ b/ch5/os/mm/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["frame_alloc","allocate a frame"],["init","initiate heap allocator, frame allocator and kernel space"],["remap_test","Check PageTable running correctly"],["translated_byte_buffer","translate a pointer to a mutable u8 Vec through page table"],["translated_refmut","translate a generic through page table and return a mutable reference"],["translated_str","translate a pointer to a mutable u8 Vec end with `\\0` through page table to a `String`"]],"mod":[["address","Implementation of physical and virtual address and page number."],["frame_allocator","Implementation of [`FrameAllocator`] which controls all the frames in the operating system."],["heap_allocator","The global allocator"],["memory_set","Implementation of [`MapArea`] and [`MemorySet`]."],["page_table","Implementation of [`PageTableEntry`] and [`PageTable`]."]],"struct":[["FrameTracker","manage a frame which has the same lifecycle as the tracker"],["KERNEL_SPACE","a memory set instance through lazy_static! managing kernel space"],["MapPermission","map permission corresponding to that in pte: `R W X U`"],["MemorySet","memory set structure, controls virtual-memory space"],["PageTableEntry","page table entry structure"],["PhysAddr","physical address"],["PhysPageNum","physical page number"],["VirtAddr","virtual address"],["VirtPageNum","virtual page number"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["frame_alloc","init","remap_test","translated_byte_buffer","translated_refmut","translated_str"],"mod":["address","frame_allocator","heap_allocator","memory_set","page_table"],"struct":["FrameTracker","KERNEL_SPACE","MapPermission","MemorySet","PageTableEntry","PhysAddr","PhysPageNum","VirtAddr","VirtPageNum"]};
\ No newline at end of file
diff --git a/ch5/os/mm/struct.FrameTracker.html b/ch5/os/mm/struct.FrameTracker.html
index 324e5f0e..14b40bfc 100644
--- a/ch5/os/mm/struct.FrameTracker.html
+++ b/ch5/os/mm/struct.FrameTracker.html
@@ -1,18 +1,15 @@
-FrameTracker in os::mm - Rust Struct os::mm::FrameTracker
source · [−]pub struct FrameTracker {
+FrameTracker in os::mm - Rust Struct os::mm::FrameTracker
source · pub struct FrameTracker {
pub ppn: PhysPageNum,
-}
Expand description
manage a frame which has the same lifecycle as the tracker
-Fields
ppn: PhysPageNum
Implementations
sourceimpl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
-Trait Implementations
sourceimpl Debug for FrameTracker
Auto Trait Implementations
impl RefUnwindSafe for FrameTracker
impl Send for FrameTracker
impl Sync for FrameTracker
impl Unpin for FrameTracker
impl UnwindSafe for FrameTracker
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
manage a frame which has the same lifecycle as the tracker
+Fields§
§ppn: PhysPageNum
Implementations§
source§impl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
+Trait Implementations§
source§impl Debug for FrameTracker
Auto Trait Implementations§
§impl RefUnwindSafe for FrameTracker
§impl Send for FrameTracker
§impl Sync for FrameTracker
§impl Unpin for FrameTracker
§impl UnwindSafe for FrameTracker
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.KERNEL_SPACE.html b/ch5/os/mm/struct.KERNEL_SPACE.html
index 50065481..a3cc6b59 100644
--- a/ch5/os/mm/struct.KERNEL_SPACE.html
+++ b/ch5/os/mm/struct.KERNEL_SPACE.html
@@ -1,17 +1,14 @@
-KERNEL_SPACE in os::mm - Rust Struct os::mm::KERNEL_SPACE
source · [−]pub struct KERNEL_SPACE {
+KERNEL_SPACE in os::mm - Rust Struct os::mm::KERNEL_SPACE
source · pub struct KERNEL_SPACE {
__private_field: (),
-}
Expand description
a memory set instance through lazy_static! managing kernel space
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for KERNEL_SPACE
type Target = Arc<UPSafeCell<MemorySet>>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<UPSafeCell<MemorySet>>
Dereferences the value.
-sourceimpl LazyStatic for KERNEL_SPACE
Auto Trait Implementations
impl RefUnwindSafe for KERNEL_SPACE
impl Send for KERNEL_SPACE
impl Sync for KERNEL_SPACE
impl Unpin for KERNEL_SPACE
impl UnwindSafe for KERNEL_SPACE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a memory set instance through lazy_static! managing kernel space
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for KERNEL_SPACE
source§impl LazyStatic for KERNEL_SPACE
Auto Trait Implementations§
§impl RefUnwindSafe for KERNEL_SPACE
§impl Send for KERNEL_SPACE
§impl Sync for KERNEL_SPACE
§impl Unpin for KERNEL_SPACE
§impl UnwindSafe for KERNEL_SPACE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.MapPermission.html b/ch5/os/mm/struct.MapPermission.html
index d276c98e..e32a1fce 100644
--- a/ch5/os/mm/struct.MapPermission.html
+++ b/ch5/os/mm/struct.MapPermission.html
@@ -1,18 +1,18 @@
-MapPermission in os::mm - Rust Struct os::mm::MapPermission
source · [−]pub struct MapPermission {
+MapPermission in os::mm - Rust Struct os::mm::MapPermission
source · pub struct MapPermission {
bits: u8,
-}
Expand description
map permission corresponding to that in pte: R W X U
-Fields
bits: u8
Implementations
sourceimpl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
map permission corresponding to that in pte: R W X U
+
Fields§
§bits: u8
Implementations§
source§impl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -20,35 +20,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -56,66 +56,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl Binary for MapPermission
sourceimpl BitAnd<MapPermission> for MapPermission
type Output = MapPermission
The resulting type after applying the &
operator.
-sourceimpl BitAndAssign<MapPermission> for MapPermission
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOr<MapPermission> for MapPermission
sourcefn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
-type Output = MapPermission
The resulting type after applying the |
operator.
-sourceimpl BitOrAssign<MapPermission> for MapPermission
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXor<MapPermission> for MapPermission
sourcefn bitxor(self, other: Self) -> Self
Returns the left flags, but with all the right flags toggled.
-type Output = MapPermission
The resulting type after applying the ^
operator.
-sourceimpl BitXorAssign<MapPermission> for MapPermission
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Clone for MapPermission
sourcefn clone(&self) -> MapPermission
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for MapPermission
sourceimpl Extend<MapPermission> for MapPermission
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<MapPermission> for MapPermission
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Hash for MapPermission
sourceimpl LowerHex for MapPermission
sourceimpl Not for MapPermission
type Output = MapPermission
The resulting type after applying the !
operator.
-sourceimpl Octal for MapPermission
sourceimpl Ord for MapPermission
sourcefn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<MapPermission> for MapPermission
sourcefn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &MapPermission) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<MapPermission> for MapPermission
sourcefn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Sub<MapPermission> for MapPermission
type Output = MapPermission
The resulting type after applying the -
operator.
-sourceimpl SubAssign<MapPermission> for MapPermission
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl UpperHex for MapPermission
sourceimpl Copy for MapPermission
sourceimpl Eq for MapPermission
sourceimpl StructuralEq for MapPermission
sourceimpl StructuralPartialEq for MapPermission
Auto Trait Implementations
impl RefUnwindSafe for MapPermission
impl Send for MapPermission
impl Sync for MapPermission
impl Unpin for MapPermission
impl UnwindSafe for MapPermission
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl Binary for MapPermission
source§impl BitAnd<MapPermission> for MapPermission
source§impl BitAndAssign<MapPermission> for MapPermission
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOr<MapPermission> for MapPermission
source§fn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
+§type Output = MapPermission
The resulting type after applying the |
operator.source§impl BitOrAssign<MapPermission> for MapPermission
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXor<MapPermission> for MapPermission
source§impl BitXorAssign<MapPermission> for MapPermission
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Clone for MapPermission
source§fn clone(&self) -> MapPermission
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for MapPermission
source§impl Extend<MapPermission> for MapPermission
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<MapPermission> for MapPermission
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Hash for MapPermission
source§impl LowerHex for MapPermission
source§impl Not for MapPermission
source§impl Octal for MapPermission
source§impl Ord for MapPermission
source§fn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<MapPermission> for MapPermission
source§fn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<MapPermission> for MapPermission
source§fn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Sub<MapPermission> for MapPermission
source§impl SubAssign<MapPermission> for MapPermission
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl UpperHex for MapPermission
source§impl Copy for MapPermission
source§impl Eq for MapPermission
source§impl StructuralEq for MapPermission
source§impl StructuralPartialEq for MapPermission
Auto Trait Implementations§
§impl RefUnwindSafe for MapPermission
§impl Send for MapPermission
§impl Sync for MapPermission
§impl Unpin for MapPermission
§impl UnwindSafe for MapPermission
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.MemorySet.html b/ch5/os/mm/struct.MemorySet.html
index 7013927d..027baf01 100644
--- a/ch5/os/mm/struct.MemorySet.html
+++ b/ch5/os/mm/struct.MemorySet.html
@@ -1,28 +1,32 @@
-MemorySet in os::mm - Rust pub struct MemorySet {
+MemorySet in os::mm - Rust Expand description
memory set structure, controls virtual-memory space
-Fields
page_table: PageTable
areas: Vec<MapArea>
Implementations
sourceimpl MemorySet
sourcepub fn insert_framed_area(
&mut self,
start_va: VirtAddr,
end_va: VirtAddr,
permission: MapPermission
)
Assume that no conflicts.
-sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
-sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
-sourcepub fn new_kernel() -> Self
Without kernel stacks.
-sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
+}Expand description
memory set structure, controls virtual-memory space
+
Fields§
§page_table: PageTable
§areas: Vec<MapArea>
Implementations§
source§impl MemorySet
sourcepub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission
+)
Assume that no conflicts.
+sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
+sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
+sourcepub fn new_kernel() -> Self
Without kernel stacks.
+sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
also returns user_sp and entry point.
-sourcepub fn from_existed_user(user_space: &Self) -> Self
Clone a same MemorySet
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
-sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
-Auto Trait Implementations
impl RefUnwindSafe for MemorySet
impl Send for MemorySet
impl Sync for MemorySet
impl Unpin for MemorySet
impl UnwindSafe for MemorySet
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
sourcepub fn from_existed_user(user_space: &Self) -> Self
Clone a same MemorySet
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
+sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
+Auto Trait Implementations§
§impl RefUnwindSafe for MemorySet
§impl Send for MemorySet
§impl Sync for MemorySet
§impl Unpin for MemorySet
§impl UnwindSafe for MemorySet
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.PageTableEntry.html b/ch5/os/mm/struct.PageTableEntry.html
index 52b02fae..57700eac 100644
--- a/ch5/os/mm/struct.PageTableEntry.html
+++ b/ch5/os/mm/struct.PageTableEntry.html
@@ -1,29 +1,24 @@
-PageTableEntry in os::mm - Rust Struct os::mm::PageTableEntry
source · [−]#[repr(C)]pub struct PageTableEntry {
+PageTableEntry in os::mm - Rust Struct os::mm::PageTableEntry
source · #[repr(C)]pub struct PageTableEntry {
pub bits: usize,
-}
Expand description
page table entry structure
-Fields
bits: usize
PTE
-Implementations
sourceimpl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
-sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
-sourcepub fn executable(&self) -> bool
Check PTE executable
-Trait Implementations
sourceimpl Clone for PageTableEntry
sourcefn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Copy for PageTableEntry
Auto Trait Implementations
impl RefUnwindSafe for PageTableEntry
impl Send for PageTableEntry
impl Sync for PageTableEntry
impl Unpin for PageTableEntry
impl UnwindSafe for PageTableEntry
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
page table entry structure
+Fields§
§bits: usize
PTE
+Implementations§
source§impl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
+sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
+sourcepub fn executable(&self) -> bool
Check PTE executable
+Trait Implementations§
source§impl Clone for PageTableEntry
source§fn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Copy for PageTableEntry
Auto Trait Implementations§
§impl RefUnwindSafe for PageTableEntry
§impl Send for PageTableEntry
§impl Sync for PageTableEntry
§impl Unpin for PageTableEntry
§impl UnwindSafe for PageTableEntry
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.PhysAddr.html b/ch5/os/mm/struct.PhysAddr.html
index eaaeb9af..12d760c8 100644
--- a/ch5/os/mm/struct.PhysAddr.html
+++ b/ch5/os/mm/struct.PhysAddr.html
@@ -1,45 +1,28 @@
-PhysAddr in os::mm - Rust pub struct PhysAddr(pub usize);
Expand description
physical address
-Tuple Fields
0: usize
Implementations
sourceimpl PhysAddr
sourcepub fn floor(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
-sourcepub fn ceil(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
-sourcepub fn page_offset(&self) -> usize
Get page offset
-sourceimpl PhysAddr
sourcepub fn get_mut<T>(&self) -> &'static mut T
Get mutable reference to PhysAddr
value
-Trait Implementations
sourceimpl From<PhysAddr> for PhysPageNum
sourceimpl From<PhysPageNum> for PhysAddr
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for PhysAddr
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
+
PhysAddr in os::mm - Rust pub struct PhysAddr(pub usize);
Expand description
physical address
+Tuple Fields§
§0: usize
Implementations§
source§impl PhysAddr
sourcepub fn floor(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
+sourcepub fn ceil(&self) -> PhysPageNum
PhysAddr
->PhysPageNum
+sourcepub fn page_offset(&self) -> usize
Get page offset
+Trait Implementations§
source§impl From<PhysAddr> for PhysPageNum
source§impl From<PhysPageNum> for PhysAddr
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for PhysAddr
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
T -> usize: T.0
usize -> T: usize.into()
-sourceimpl Ord for PhysAddr
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialOrd<PhysAddr> for PhysAddr
sourcefn partial_cmp(&self, other: &PhysAddr) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for PhysAddr
sourceimpl Eq for PhysAddr
sourceimpl StructuralEq for PhysAddr
sourceimpl StructuralPartialEq for PhysAddr
Auto Trait Implementations
impl RefUnwindSafe for PhysAddr
impl Send for PhysAddr
impl Sync for PhysAddr
impl Unpin for PhysAddr
impl UnwindSafe for PhysAddr
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
source§impl Ord for PhysAddr
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PhysAddr> for PhysAddr
source§impl PartialOrd<PhysAddr> for PhysAddr
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for PhysAddr
source§impl Eq for PhysAddr
source§impl StructuralEq for PhysAddr
source§impl StructuralPartialEq for PhysAddr
Auto Trait Implementations§
§impl RefUnwindSafe for PhysAddr
§impl Send for PhysAddr
§impl Sync for PhysAddr
§impl Unpin for PhysAddr
§impl UnwindSafe for PhysAddr
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.PhysPageNum.html b/ch5/os/mm/struct.PhysPageNum.html
index 38db20b0..7d758b9d 100644
--- a/ch5/os/mm/struct.PhysPageNum.html
+++ b/ch5/os/mm/struct.PhysPageNum.html
@@ -1,38 +1,21 @@
-PhysPageNum in os::mm - Rust Struct os::mm::PhysPageNum
source · [−]pub struct PhysPageNum(pub usize);
Expand description
physical page number
-Tuple Fields
0: usize
Implementations
sourceimpl PhysPageNum
sourcepub fn get_pte_array(&self) -> &'static mut [PageTableEntry]
Get PageTableEntry
on PhysPageNum
-sourcepub fn get_bytes_array(&self) -> &'static mut [u8]
sourcepub fn get_mut<T>(&self) -> &'static mut T
Trait Implementations
sourceimpl Clone for PhysPageNum
sourcefn clone(&self) -> PhysPageNum
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for PhysPageNum
sourceimpl From<PhysAddr> for PhysPageNum
sourceimpl From<PhysPageNum> for PhysAddr
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<PhysPageNum> for usize
sourcefn from(v: PhysPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for PhysPageNum
sourceimpl Ord for PhysPageNum
sourcefn cmp(&self, other: &PhysPageNum) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<PhysPageNum> for PhysPageNum
sourcefn eq(&self, other: &PhysPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &PhysPageNum) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<PhysPageNum> for PhysPageNum
sourcefn partial_cmp(&self, other: &PhysPageNum) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for PhysPageNum
sourceimpl Eq for PhysPageNum
sourceimpl StructuralEq for PhysPageNum
sourceimpl StructuralPartialEq for PhysPageNum
Auto Trait Implementations
impl RefUnwindSafe for PhysPageNum
impl Send for PhysPageNum
impl Sync for PhysPageNum
impl Unpin for PhysPageNum
impl UnwindSafe for PhysPageNum
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+PhysPageNum in os::mm - Rust Struct os::mm::PhysPageNum
source · pub struct PhysPageNum(pub usize);
Expand description
physical page number
+Tuple Fields§
§0: usize
Implementations§
source§impl PhysPageNum
sourcepub fn get_pte_array(&self) -> &'static mut [PageTableEntry]
Get PageTableEntry
on PhysPageNum
+sourcepub fn get_bytes_array(&self) -> &'static mut [u8]
sourcepub fn get_mut<T>(&self) -> &'static mut T
Trait Implementations§
source§impl Clone for PhysPageNum
source§fn clone(&self) -> PhysPageNum
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for PhysPageNum
source§impl From<PhysAddr> for PhysPageNum
source§impl From<PhysPageNum> for PhysAddr
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<PhysPageNum> for usize
source§fn from(v: PhysPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for PhysPageNum
source§impl Ord for PhysPageNum
source§fn cmp(&self, other: &PhysPageNum) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PhysPageNum> for PhysPageNum
source§fn eq(&self, other: &PhysPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<PhysPageNum> for PhysPageNum
source§fn partial_cmp(&self, other: &PhysPageNum) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for PhysPageNum
source§impl Eq for PhysPageNum
source§impl StructuralEq for PhysPageNum
source§impl StructuralPartialEq for PhysPageNum
Auto Trait Implementations§
§impl RefUnwindSafe for PhysPageNum
§impl Send for PhysPageNum
§impl Sync for PhysPageNum
§impl Unpin for PhysPageNum
§impl UnwindSafe for PhysPageNum
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.VirtAddr.html b/ch5/os/mm/struct.VirtAddr.html
index 6c26d123..01556bb3 100644
--- a/ch5/os/mm/struct.VirtAddr.html
+++ b/ch5/os/mm/struct.VirtAddr.html
@@ -1,42 +1,25 @@
-VirtAddr in os::mm - Rust pub struct VirtAddr(pub usize);
Expand description
virtual address
-Tuple Fields
0: usize
Implementations
sourceimpl VirtAddr
sourcepub fn floor(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
-sourcepub fn ceil(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
-sourcepub fn page_offset(&self) -> usize
Get page offset
-Trait Implementations
sourceimpl From<VirtAddr> for VirtPageNum
sourceimpl From<VirtPageNum> for VirtAddr
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl Ord for VirtAddr
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialOrd<VirtAddr> for VirtAddr
sourcefn partial_cmp(&self, other: &VirtAddr) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Copy for VirtAddr
sourceimpl Eq for VirtAddr
sourceimpl StructuralEq for VirtAddr
sourceimpl StructuralPartialEq for VirtAddr
Auto Trait Implementations
impl RefUnwindSafe for VirtAddr
impl Send for VirtAddr
impl Sync for VirtAddr
impl Unpin for VirtAddr
impl UnwindSafe for VirtAddr
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+VirtAddr in os::mm - Rust pub struct VirtAddr(pub usize);
Expand description
virtual address
+Tuple Fields§
§0: usize
Implementations§
source§impl VirtAddr
sourcepub fn floor(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
+sourcepub fn ceil(&self) -> VirtPageNum
VirtAddr
->VirtPageNum
+sourcepub fn page_offset(&self) -> usize
Get page offset
+Trait Implementations§
source§impl From<VirtAddr> for VirtPageNum
source§impl From<VirtPageNum> for VirtAddr
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl Ord for VirtAddr
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<VirtAddr> for VirtAddr
source§impl PartialOrd<VirtAddr> for VirtAddr
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for VirtAddr
source§impl Eq for VirtAddr
source§impl StructuralEq for VirtAddr
source§impl StructuralPartialEq for VirtAddr
Auto Trait Implementations§
§impl RefUnwindSafe for VirtAddr
§impl Send for VirtAddr
§impl Sync for VirtAddr
§impl Unpin for VirtAddr
§impl UnwindSafe for VirtAddr
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/mm/struct.VirtPageNum.html b/ch5/os/mm/struct.VirtPageNum.html
index cf2ce74e..13c8fc3f 100644
--- a/ch5/os/mm/struct.VirtPageNum.html
+++ b/ch5/os/mm/struct.VirtPageNum.html
@@ -1,38 +1,21 @@
-VirtPageNum in os::mm - Rust Struct os::mm::VirtPageNum
source · [−]pub struct VirtPageNum(pub usize);
Expand description
virtual page number
-Tuple Fields
0: usize
Implementations
Trait Implementations
sourceimpl Clone for VirtPageNum
sourcefn clone(&self) -> VirtPageNum
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for VirtPageNum
sourceimpl From<VirtAddr> for VirtPageNum
sourceimpl From<VirtPageNum> for VirtAddr
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<VirtPageNum> for usize
sourcefn from(v: VirtPageNum) -> Self
Converts to this type from the input type.
-sourceimpl From<usize> for VirtPageNum
sourceimpl Ord for VirtPageNum
sourcefn cmp(&self, other: &VirtPageNum) -> Ordering
1.21.0 · sourcefn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
-1.21.0 · sourcefn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
-1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
-sourceimpl PartialEq<VirtPageNum> for VirtPageNum
sourcefn eq(&self, other: &VirtPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &VirtPageNum) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<VirtPageNum> for VirtPageNum
sourcefn partial_cmp(&self, other: &VirtPageNum) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl StepByOne for VirtPageNum
sourceimpl Copy for VirtPageNum
sourceimpl Eq for VirtPageNum
sourceimpl StructuralEq for VirtPageNum
sourceimpl StructuralPartialEq for VirtPageNum
Auto Trait Implementations
impl RefUnwindSafe for VirtPageNum
impl Send for VirtPageNum
impl Sync for VirtPageNum
impl Unpin for VirtPageNum
impl UnwindSafe for VirtPageNum
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+VirtPageNum in os::mm - Rust Struct os::mm::VirtPageNum
source · pub struct VirtPageNum(pub usize);
Expand description
virtual page number
+Tuple Fields§
§0: usize
Implementations§
Trait Implementations§
source§impl Clone for VirtPageNum
source§fn clone(&self) -> VirtPageNum
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for VirtPageNum
source§impl From<VirtAddr> for VirtPageNum
source§impl From<VirtPageNum> for VirtAddr
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl From<VirtPageNum> for usize
source§fn from(v: VirtPageNum) -> Self
Converts to this type from the input type.source§impl From<usize> for VirtPageNum
source§impl Ord for VirtPageNum
source§fn cmp(&self, other: &VirtPageNum) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<VirtPageNum> for VirtPageNum
source§fn eq(&self, other: &VirtPageNum) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<VirtPageNum> for VirtPageNum
source§fn partial_cmp(&self, other: &VirtPageNum) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Copy for VirtPageNum
source§impl Eq for VirtPageNum
source§impl StructuralEq for VirtPageNum
source§impl StructuralPartialEq for VirtPageNum
Auto Trait Implementations§
§impl RefUnwindSafe for VirtPageNum
§impl Send for VirtPageNum
§impl Sync for VirtPageNum
§impl Unpin for VirtPageNum
§impl UnwindSafe for VirtPageNum
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/sbi/fn.console_getchar.html b/ch5/os/sbi/fn.console_getchar.html
index 59c93774..f480a50a 100644
--- a/ch5/os/sbi/fn.console_getchar.html
+++ b/ch5/os/sbi/fn.console_getchar.html
@@ -1,2 +1,2 @@
-console_getchar in os::sbi - Rust
\ No newline at end of file
+console_getchar in os::sbi - Rust Function os::sbi::console_getchar
source · pub fn console_getchar() -> usize
Expand description
use sbi call to getchar from console (qemu uart handler)
+
\ No newline at end of file
diff --git a/ch5/os/sbi/fn.console_putchar.html b/ch5/os/sbi/fn.console_putchar.html
index 40cb32c3..e56c8eb0 100644
--- a/ch5/os/sbi/fn.console_putchar.html
+++ b/ch5/os/sbi/fn.console_putchar.html
@@ -1,2 +1,2 @@
-console_putchar in os::sbi - Rust
\ No newline at end of file
+console_putchar in os::sbi - Rust Function os::sbi::console_putchar
source · pub fn console_putchar(c: usize)
Expand description
use sbi call to putchar in console (qemu uart handler)
+
\ No newline at end of file
diff --git a/ch5/os/sbi/fn.set_timer.html b/ch5/os/sbi/fn.set_timer.html
index fbb76cb8..84acf5eb 100644
--- a/ch5/os/sbi/fn.set_timer.html
+++ b/ch5/os/sbi/fn.set_timer.html
@@ -1,2 +1,2 @@
-set_timer in os::sbi - Rust
\ No newline at end of file
+set_timer in os::sbi - Rust
\ No newline at end of file
diff --git a/ch5/os/sbi/fn.shutdown.html b/ch5/os/sbi/fn.shutdown.html
index 6f6177b1..8c2a956b 100644
--- a/ch5/os/sbi/fn.shutdown.html
+++ b/ch5/os/sbi/fn.shutdown.html
@@ -1,2 +1,2 @@
-shutdown in os::sbi - Rust
\ No newline at end of file
+shutdown in os::sbi - Rust
\ No newline at end of file
diff --git a/ch5/os/sbi/index.html b/ch5/os/sbi/index.html
index b9bba0c9..90c24f2b 100644
--- a/ch5/os/sbi/index.html
+++ b/ch5/os/sbi/index.html
@@ -1,6 +1,2 @@
-os::sbi - Rust Expand description
SBI call wrappers
-Functions
use sbi call to getchar from console (qemu uart handler)
-use sbi call to putchar in console (qemu uart handler)
-use sbi call to set timer
-use sbi call to shutdown the kernel
-
\ No newline at end of file
+os::sbi - Rust Expand description
SBI call wrappers
+Functions
- use sbi call to getchar from console (qemu uart handler)
- use sbi call to putchar in console (qemu uart handler)
- use sbi call to set timer
- use sbi call to shutdown the kernel
\ No newline at end of file
diff --git a/ch5/os/sbi/sidebar-items.js b/ch5/os/sbi/sidebar-items.js
index 9c54a354..48cbb3c3 100644
--- a/ch5/os/sbi/sidebar-items.js
+++ b/ch5/os/sbi/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["console_getchar","use sbi call to getchar from console (qemu uart handler)"],["console_putchar","use sbi call to putchar in console (qemu uart handler)"],["set_timer","use sbi call to set timer"],["shutdown","use sbi call to shutdown the kernel"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["console_getchar","console_putchar","set_timer","shutdown"]};
\ No newline at end of file
diff --git a/ch5/os/sidebar-items.js b/ch5/os/sidebar-items.js
index 82ae13f8..54d7ece7 100644
--- a/ch5/os/sidebar-items.js
+++ b/ch5/os/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["clear_bss","clear BSS segment"],["rust_main","the rust entry-point of os"]],"macro":[["print","print string macro"],["println","println string macro"]],"mod":[["board","Constants used in rCore for qemu"],["config","Constants used in rCore"],["console","SBI console driver, for text output"],["lang_items","The panic handler"],["loader","Loading user applications into memory"],["mm","Memory management implementation"],["sbi","SBI call wrappers"],["sync","Synchronization and interior mutability primitives"],["syscall","Implementation of syscalls"],["task","Task management implementation"],["timer","RISC-V timer-related functionality"],["trap","Trap handling functionality"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["clear_bss","rust_main"],"macro":["print","println"],"mod":["board","config","console","lang_items","loader","mm","sbi","sync","syscall","task","timer","trap"]};
\ No newline at end of file
diff --git a/ch5/os/sync/index.html b/ch5/os/sync/index.html
index 4391bcb7..3c6c371d 100644
--- a/ch5/os/sync/index.html
+++ b/ch5/os/sync/index.html
@@ -1,5 +1,3 @@
-os::sync - Rust
\ No newline at end of file
+os::sync - Rust
\ No newline at end of file
diff --git a/ch5/os/sync/sidebar-items.js b/ch5/os/sync/sidebar-items.js
index 751ae6d5..fdf90b45 100644
--- a/ch5/os/sync/sidebar-items.js
+++ b/ch5/os/sync/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"mod":[["up","Uniprocessor interior mutability primitives"]],"struct":[["UPSafeCell","Wrap a static data structure inside it so that we are able to access it without any `unsafe`."]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"mod":["up"],"struct":["UPSafeCell"]};
\ No newline at end of file
diff --git a/ch5/os/sync/struct.UPSafeCell.html b/ch5/os/sync/struct.UPSafeCell.html
index 1ccb3c0b..7e6fe872 100644
--- a/ch5/os/sync/struct.UPSafeCell.html
+++ b/ch5/os/sync/struct.UPSafeCell.html
@@ -1,23 +1,25 @@
-UPSafeCell in os::sync - Rust Struct os::sync::UPSafeCell
source · [−]pub struct UPSafeCell<T> {
+UPSafeCell in os::sync - Rust Struct os::sync::UPSafeCell
source · pub struct UPSafeCell<T> {
inner: RefCell<T>,
-}
Expand description
Wrap a static data structure inside it so that we are
+}Expand description
Wrap a static data structure inside it so that we are
able to access it without any unsafe
.
We should only use it in uniprocessor.
In order to get mutable reference of inner data, call
exclusive_access
.
-
Fields
inner: RefCell<T>
inner data
-Implementations
sourceimpl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
+
Fields§
§inner: RefCell<T>
inner data
+Implementations§
source§impl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
uniprocessor.
-sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl<T> Sync for UPSafeCell<T>
Auto Trait Implementations
impl<T> !RefUnwindSafe for UPSafeCell<T>
impl<T> Send for UPSafeCell<T> where
T: Send,
impl<T> Unpin for UPSafeCell<T> where
T: Unpin,
impl<T> UnwindSafe for UPSafeCell<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl<T> Sync for UPSafeCell<T>
Auto Trait Implementations§
§impl<T> !RefUnwindSafe for UPSafeCell<T>
§impl<T> Send for UPSafeCell<T>where
+ T: Send,
§impl<T> Unpin for UPSafeCell<T>where
+ T: Unpin,
§impl<T> UnwindSafe for UPSafeCell<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/sync/up/index.html b/ch5/os/sync/up/index.html
index 45ca888e..e6457b0e 100644
--- a/ch5/os/sync/up/index.html
+++ b/ch5/os/sync/up/index.html
@@ -1,4 +1,3 @@
-os::sync::up - Rust
\ No newline at end of file
+os::sync::up - Rust
\ No newline at end of file
diff --git a/ch5/os/sync/up/sidebar-items.js b/ch5/os/sync/up/sidebar-items.js
index 8f4cda09..f4e9455d 100644
--- a/ch5/os/sync/up/sidebar-items.js
+++ b/ch5/os/sync/up/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"struct":[["UPSafeCell","Wrap a static data structure inside it so that we are able to access it without any `unsafe`."]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"struct":["UPSafeCell"]};
\ No newline at end of file
diff --git a/ch5/os/sync/up/struct.UPSafeCell.html b/ch5/os/sync/up/struct.UPSafeCell.html
index 67f15826..18e9ee32 100644
--- a/ch5/os/sync/up/struct.UPSafeCell.html
+++ b/ch5/os/sync/up/struct.UPSafeCell.html
@@ -1,23 +1,25 @@
-UPSafeCell in os::sync::up - Rust pub struct UPSafeCell<T> {
+UPSafeCell in os::sync::up - Rust Expand description
Wrap a static data structure inside it so that we are
+}Expand description
Wrap a static data structure inside it so that we are
able to access it without any unsafe
.
We should only use it in uniprocessor.
In order to get mutable reference of inner data, call
exclusive_access
.
-
Fields
inner: RefCell<T>
inner data
-Implementations
sourceimpl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
+
Fields§
§inner: RefCell<T>
inner data
+Implementations§
source§impl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
uniprocessor.
-sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl<T> Sync for UPSafeCell<T>
Auto Trait Implementations
impl<T> !RefUnwindSafe for UPSafeCell<T>
impl<T> Send for UPSafeCell<T> where
T: Send,
impl<T> Unpin for UPSafeCell<T> where
T: Unpin,
impl<T> UnwindSafe for UPSafeCell<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl<T> Sync for UPSafeCell<T>
Auto Trait Implementations§
§impl<T> !RefUnwindSafe for UPSafeCell<T>
§impl<T> Send for UPSafeCell<T>where
+ T: Send,
§impl<T> Unpin for UPSafeCell<T>where
+ T: Unpin,
§impl<T> UnwindSafe for UPSafeCell<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_EXEC.html b/ch5/os/syscall/constant.SYSCALL_EXEC.html
index 408ccaaf..b9b060c5 100644
--- a/ch5/os/syscall/constant.SYSCALL_EXEC.html
+++ b/ch5/os/syscall/constant.SYSCALL_EXEC.html
@@ -1 +1 @@
-SYSCALL_EXEC in os::syscall - Rust
\ No newline at end of file
+SYSCALL_EXEC in os::syscall - Rust Constant os::syscall::SYSCALL_EXEC
source · const SYSCALL_EXEC: usize = 221;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_EXIT.html b/ch5/os/syscall/constant.SYSCALL_EXIT.html
index cb68704e..4865fd4a 100644
--- a/ch5/os/syscall/constant.SYSCALL_EXIT.html
+++ b/ch5/os/syscall/constant.SYSCALL_EXIT.html
@@ -1 +1 @@
-SYSCALL_EXIT in os::syscall - Rust
\ No newline at end of file
+SYSCALL_EXIT in os::syscall - Rust Constant os::syscall::SYSCALL_EXIT
source · const SYSCALL_EXIT: usize = 93;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_FORK.html b/ch5/os/syscall/constant.SYSCALL_FORK.html
index 689bbd85..6ef06bc7 100644
--- a/ch5/os/syscall/constant.SYSCALL_FORK.html
+++ b/ch5/os/syscall/constant.SYSCALL_FORK.html
@@ -1 +1 @@
-SYSCALL_FORK in os::syscall - Rust
\ No newline at end of file
+SYSCALL_FORK in os::syscall - Rust Constant os::syscall::SYSCALL_FORK
source · const SYSCALL_FORK: usize = 220;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_GETPID.html b/ch5/os/syscall/constant.SYSCALL_GETPID.html
index 58c41607..39cbb1d4 100644
--- a/ch5/os/syscall/constant.SYSCALL_GETPID.html
+++ b/ch5/os/syscall/constant.SYSCALL_GETPID.html
@@ -1 +1 @@
-SYSCALL_GETPID in os::syscall - Rust
\ No newline at end of file
+SYSCALL_GETPID in os::syscall - Rust Constant os::syscall::SYSCALL_GETPID
source · const SYSCALL_GETPID: usize = 172;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_GET_TIME.html b/ch5/os/syscall/constant.SYSCALL_GET_TIME.html
index 1f28ac14..b4068dff 100644
--- a/ch5/os/syscall/constant.SYSCALL_GET_TIME.html
+++ b/ch5/os/syscall/constant.SYSCALL_GET_TIME.html
@@ -1 +1 @@
-SYSCALL_GET_TIME in os::syscall - Rust
\ No newline at end of file
+SYSCALL_GET_TIME in os::syscall - Rust Constant os::syscall::SYSCALL_GET_TIME
source · const SYSCALL_GET_TIME: usize = 169;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_READ.html b/ch5/os/syscall/constant.SYSCALL_READ.html
index e480131b..dde4a148 100644
--- a/ch5/os/syscall/constant.SYSCALL_READ.html
+++ b/ch5/os/syscall/constant.SYSCALL_READ.html
@@ -1 +1 @@
-SYSCALL_READ in os::syscall - Rust
\ No newline at end of file
+SYSCALL_READ in os::syscall - Rust Constant os::syscall::SYSCALL_READ
source · const SYSCALL_READ: usize = 63;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_WAITPID.html b/ch5/os/syscall/constant.SYSCALL_WAITPID.html
index 90017fd4..661521fc 100644
--- a/ch5/os/syscall/constant.SYSCALL_WAITPID.html
+++ b/ch5/os/syscall/constant.SYSCALL_WAITPID.html
@@ -1 +1 @@
-SYSCALL_WAITPID in os::syscall - Rust
\ No newline at end of file
+SYSCALL_WAITPID in os::syscall - Rust Constant os::syscall::SYSCALL_WAITPID
source · const SYSCALL_WAITPID: usize = 260;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_WRITE.html b/ch5/os/syscall/constant.SYSCALL_WRITE.html
index d90f659f..bc8eff8a 100644
--- a/ch5/os/syscall/constant.SYSCALL_WRITE.html
+++ b/ch5/os/syscall/constant.SYSCALL_WRITE.html
@@ -1 +1 @@
-SYSCALL_WRITE in os::syscall - Rust
\ No newline at end of file
+SYSCALL_WRITE in os::syscall - Rust Constant os::syscall::SYSCALL_WRITE
source · const SYSCALL_WRITE: usize = 64;
\ No newline at end of file
diff --git a/ch5/os/syscall/constant.SYSCALL_YIELD.html b/ch5/os/syscall/constant.SYSCALL_YIELD.html
index b4d92a07..8d3d5c0c 100644
--- a/ch5/os/syscall/constant.SYSCALL_YIELD.html
+++ b/ch5/os/syscall/constant.SYSCALL_YIELD.html
@@ -1 +1 @@
-SYSCALL_YIELD in os::syscall - Rust
\ No newline at end of file
+SYSCALL_YIELD in os::syscall - Rust Constant os::syscall::SYSCALL_YIELD
source · const SYSCALL_YIELD: usize = 124;
\ No newline at end of file
diff --git a/ch5/os/syscall/fn.syscall.html b/ch5/os/syscall/fn.syscall.html
index 97700b56..518d4f18 100644
--- a/ch5/os/syscall/fn.syscall.html
+++ b/ch5/os/syscall/fn.syscall.html
@@ -1,2 +1,2 @@
-syscall in os::syscall - Rust
\ No newline at end of file
+syscall in os::syscall - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/constant.FD_STDIN.html b/ch5/os/syscall/fs/constant.FD_STDIN.html
index a0ccbe97..1c124785 100644
--- a/ch5/os/syscall/fs/constant.FD_STDIN.html
+++ b/ch5/os/syscall/fs/constant.FD_STDIN.html
@@ -1 +1 @@
-FD_STDIN in os::syscall::fs - Rust
\ No newline at end of file
+FD_STDIN in os::syscall::fs - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/constant.FD_STDOUT.html b/ch5/os/syscall/fs/constant.FD_STDOUT.html
index 79699600..5f3f80dd 100644
--- a/ch5/os/syscall/fs/constant.FD_STDOUT.html
+++ b/ch5/os/syscall/fs/constant.FD_STDOUT.html
@@ -1 +1 @@
-FD_STDOUT in os::syscall::fs - Rust
\ No newline at end of file
+FD_STDOUT in os::syscall::fs - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/fn.sys_read.html b/ch5/os/syscall/fs/fn.sys_read.html
index 4b85606f..6cac225e 100644
--- a/ch5/os/syscall/fs/fn.sys_read.html
+++ b/ch5/os/syscall/fs/fn.sys_read.html
@@ -1 +1 @@
-sys_read in os::syscall::fs - Rust
\ No newline at end of file
+sys_read in os::syscall::fs - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/fn.sys_write.html b/ch5/os/syscall/fs/fn.sys_write.html
index 22709f39..b3a67e60 100644
--- a/ch5/os/syscall/fs/fn.sys_write.html
+++ b/ch5/os/syscall/fs/fn.sys_write.html
@@ -1 +1 @@
-sys_write in os::syscall::fs - Rust
\ No newline at end of file
+sys_write in os::syscall::fs - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/index.html b/ch5/os/syscall/fs/index.html
index 6366c0f2..a15556ca 100644
--- a/ch5/os/syscall/fs/index.html
+++ b/ch5/os/syscall/fs/index.html
@@ -1,2 +1,2 @@
-os::syscall::fs - Rust
\ No newline at end of file
+os::syscall::fs - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/fs/sidebar-items.js b/ch5/os/syscall/fs/sidebar-items.js
index 8b470869..54b4bbb3 100644
--- a/ch5/os/syscall/fs/sidebar-items.js
+++ b/ch5/os/syscall/fs/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"constant":[["FD_STDIN",""],["FD_STDOUT",""]],"fn":[["sys_read",""],["sys_write",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"constant":["FD_STDIN","FD_STDOUT"],"fn":["sys_read","sys_write"]};
\ No newline at end of file
diff --git a/ch5/os/syscall/index.html b/ch5/os/syscall/index.html
index 758ccc32..8cb869ad 100644
--- a/ch5/os/syscall/index.html
+++ b/ch5/os/syscall/index.html
@@ -1,12 +1,10 @@
-os::syscall - Rust Expand description
Implementation of syscalls
-The single entry point to all system calls, syscall()
, is called
+
os::syscall - Rust Expand description
Implementation of syscalls
+The single entry point to all system calls, syscall()
, is called
whenever userspace wishes to perform a system call using the ecall
instruction. In this case, the processor raises an ‘Environment call from
U-mode’ exception, which is handled as one of the cases in
-crate::trap::trap_handler
.
+crate::trap::trap_handler
.
For clarity, each single syscall is implemented as its own function, named
sys_
then the name of the syscall. You can find functions like this in
submodules, and you should also implement syscalls this way.
-Modules
Constants
Functions
handle syscall exception with syscall_id
and other arguments
-
\ No newline at end of file
+Modules
Constants
Functions
- handle syscall exception with
syscall_id
and other arguments
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_exec.html b/ch5/os/syscall/process/fn.sys_exec.html
index 5e563bef..efb92cff 100644
--- a/ch5/os/syscall/process/fn.sys_exec.html
+++ b/ch5/os/syscall/process/fn.sys_exec.html
@@ -1 +1 @@
-sys_exec in os::syscall::process - Rust
\ No newline at end of file
+sys_exec in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_exit.html b/ch5/os/syscall/process/fn.sys_exit.html
index 60539219..6d684faf 100644
--- a/ch5/os/syscall/process/fn.sys_exit.html
+++ b/ch5/os/syscall/process/fn.sys_exit.html
@@ -1 +1 @@
-sys_exit in os::syscall::process - Rust
\ No newline at end of file
+sys_exit in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_fork.html b/ch5/os/syscall/process/fn.sys_fork.html
index cc84139a..e56df4b8 100644
--- a/ch5/os/syscall/process/fn.sys_fork.html
+++ b/ch5/os/syscall/process/fn.sys_fork.html
@@ -1 +1 @@
-sys_fork in os::syscall::process - Rust
\ No newline at end of file
+sys_fork in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_get_time.html b/ch5/os/syscall/process/fn.sys_get_time.html
index 6f3c273d..5d5f7a7e 100644
--- a/ch5/os/syscall/process/fn.sys_get_time.html
+++ b/ch5/os/syscall/process/fn.sys_get_time.html
@@ -1 +1 @@
-sys_get_time in os::syscall::process - Rust
\ No newline at end of file
+sys_get_time in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_getpid.html b/ch5/os/syscall/process/fn.sys_getpid.html
index beb07c1d..e11ffb87 100644
--- a/ch5/os/syscall/process/fn.sys_getpid.html
+++ b/ch5/os/syscall/process/fn.sys_getpid.html
@@ -1 +1 @@
-sys_getpid in os::syscall::process - Rust
\ No newline at end of file
+sys_getpid in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_waitpid.html b/ch5/os/syscall/process/fn.sys_waitpid.html
index 90a4599f..d3de8173 100644
--- a/ch5/os/syscall/process/fn.sys_waitpid.html
+++ b/ch5/os/syscall/process/fn.sys_waitpid.html
@@ -1,3 +1,3 @@
-sys_waitpid in os::syscall::process - Rust Expand description
If there is not a child process whose pid is same as given, return -1.
+
sys_waitpid in os::syscall::process - Rust
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/os/syscall/process/fn.sys_yield.html b/ch5/os/syscall/process/fn.sys_yield.html
index 06c09463..9394cfd2 100644
--- a/ch5/os/syscall/process/fn.sys_yield.html
+++ b/ch5/os/syscall/process/fn.sys_yield.html
@@ -1 +1 @@
-sys_yield in os::syscall::process - Rust
\ No newline at end of file
+sys_yield in os::syscall::process - Rust
\ No newline at end of file
diff --git a/ch5/os/syscall/process/index.html b/ch5/os/syscall/process/index.html
index 1f0d3fdc..0cfaaa38 100644
--- a/ch5/os/syscall/process/index.html
+++ b/ch5/os/syscall/process/index.html
@@ -1,3 +1,2 @@
-os::syscall::process - Rust Functions
If there is not a child process whose pid is same as given, return -1.
-Else if there is a child process but it is still running, return -2.
-
\ No newline at end of file
+os::syscall::process - Rust Functions
- If there is not a child process whose pid is same as given, return -1.
+Else if there is a child process but it is still running, return -2.
\ No newline at end of file
diff --git a/ch5/os/syscall/process/sidebar-items.js b/ch5/os/syscall/process/sidebar-items.js
index 3f73be9e..c7cff172 100644
--- a/ch5/os/syscall/process/sidebar-items.js
+++ b/ch5/os/syscall/process/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["sys_exec",""],["sys_exit",""],["sys_fork",""],["sys_get_time",""],["sys_getpid",""],["sys_waitpid","If there is not a child process whose pid is same as given, return -1. Else if there is a child process but it is still running, return -2."],["sys_yield",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["sys_exec","sys_exit","sys_fork","sys_get_time","sys_getpid","sys_waitpid","sys_yield"]};
\ No newline at end of file
diff --git a/ch5/os/syscall/sidebar-items.js b/ch5/os/syscall/sidebar-items.js
index 57039b41..2803b8b0 100644
--- a/ch5/os/syscall/sidebar-items.js
+++ b/ch5/os/syscall/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"constant":[["SYSCALL_EXEC",""],["SYSCALL_EXIT",""],["SYSCALL_FORK",""],["SYSCALL_GETPID",""],["SYSCALL_GET_TIME",""],["SYSCALL_READ",""],["SYSCALL_WAITPID",""],["SYSCALL_WRITE",""],["SYSCALL_YIELD",""]],"fn":[["syscall","handle syscall exception with `syscall_id` and other arguments"]],"mod":[["fs","File and filesystem-related syscalls"],["process",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"constant":["SYSCALL_EXEC","SYSCALL_EXIT","SYSCALL_FORK","SYSCALL_GETPID","SYSCALL_GET_TIME","SYSCALL_READ","SYSCALL_WAITPID","SYSCALL_WRITE","SYSCALL_YIELD"],"fn":["syscall"],"mod":["fs","process"]};
\ No newline at end of file
diff --git a/ch5/os/task/constant.IDLE_PID.html b/ch5/os/task/constant.IDLE_PID.html
index 15ad6d76..421c316c 100644
--- a/ch5/os/task/constant.IDLE_PID.html
+++ b/ch5/os/task/constant.IDLE_PID.html
@@ -1,2 +1,2 @@
-IDLE_PID in os::task - Rust
\ No newline at end of file
+IDLE_PID in os::task - Rust
\ No newline at end of file
diff --git a/ch5/os/task/context/index.html b/ch5/os/task/context/index.html
index 9240d663..0fed0d17 100644
--- a/ch5/os/task/context/index.html
+++ b/ch5/os/task/context/index.html
@@ -1,3 +1,2 @@
-os::task::context - Rust Expand description
Implementation of TaskContext
-Structs
task context structure containing some registers
-
\ No newline at end of file
+os::task::context - Rust Expand description
Implementation of TaskContext
+Structs
- task context structure containing some registers
\ No newline at end of file
diff --git a/ch5/os/task/context/sidebar-items.js b/ch5/os/task/context/sidebar-items.js
index a33372da..f64436cc 100644
--- a/ch5/os/task/context/sidebar-items.js
+++ b/ch5/os/task/context/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"struct":[["TaskContext","task context structure containing some registers"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"struct":["TaskContext"]};
\ No newline at end of file
diff --git a/ch5/os/task/context/struct.TaskContext.html b/ch5/os/task/context/struct.TaskContext.html
index 7cfcb451..49ceaaf9 100644
--- a/ch5/os/task/context/struct.TaskContext.html
+++ b/ch5/os/task/context/struct.TaskContext.html
@@ -1,22 +1,21 @@
-TaskContext in os::task::context - Rust #[repr(C)]pub struct TaskContext {
+TaskContext in os::task::context - Rust Struct os::task::context::TaskContext
source · #[repr(C)]pub struct TaskContext {
ra: usize,
sp: usize,
- s: [usize; 12],
-}
Expand description
task context structure containing some registers
-Fields
ra: usize
return address ( e.g. __restore ) of __switch ASM function
-sp: usize
kernel stack pointer of app
-s: [usize; 12]
s0-11 register, callee saved
-Implementations
sourceimpl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
-Auto Trait Implementations
impl RefUnwindSafe for TaskContext
impl Send for TaskContext
impl Sync for TaskContext
impl Unpin for TaskContext
impl UnwindSafe for TaskContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+ s: [usize; 12],
+}Expand description
task context structure containing some registers
+Fields§
§ra: usize
return address ( e.g. __restore ) of __switch ASM function
+§sp: usize
kernel stack pointer of app
+§s: [usize; 12]
s0-11 register, callee saved
+Implementations§
source§impl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+Auto Trait Implementations§
§impl RefUnwindSafe for TaskContext
§impl Send for TaskContext
§impl Sync for TaskContext
§impl Unpin for TaskContext
§impl UnwindSafe for TaskContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.add_initproc.html b/ch5/os/task/fn.add_initproc.html
index 24626332..06a045d5 100644
--- a/ch5/os/task/fn.add_initproc.html
+++ b/ch5/os/task/fn.add_initproc.html
@@ -1,2 +1,2 @@
-add_initproc in os::task - Rust Function os::task::add_initproc
source · [−]pub fn add_initproc()
Expand description
Add init process to the manager
-
\ No newline at end of file
+add_initproc in os::task - Rust Function os::task::add_initproc
source · pub fn add_initproc()
Expand description
Add init process to the manager
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.add_task.html b/ch5/os/task/fn.add_task.html
index 518f842e..c88b999b 100644
--- a/ch5/os/task/fn.add_task.html
+++ b/ch5/os/task/fn.add_task.html
@@ -1,2 +1,2 @@
-add_task in os::task - Rust
\ No newline at end of file
+add_task in os::task - Rust
\ No newline at end of file
diff --git a/ch5/os/task/fn.current_task.html b/ch5/os/task/fn.current_task.html
index e18ee964..8306af47 100644
--- a/ch5/os/task/fn.current_task.html
+++ b/ch5/os/task/fn.current_task.html
@@ -1,2 +1,2 @@
-current_task in os::task - Rust Function os::task::current_task
source · [−]pub fn current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Get running task
-
\ No newline at end of file
+current_task in os::task - Rust Function os::task::current_task
source · pub fn current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Get running task
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.current_trap_cx.html b/ch5/os/task/fn.current_trap_cx.html
index 031ba95f..293cd33c 100644
--- a/ch5/os/task/fn.current_trap_cx.html
+++ b/ch5/os/task/fn.current_trap_cx.html
@@ -1,2 +1,2 @@
-current_trap_cx in os::task - Rust Function os::task::current_trap_cx
source · [−]pub fn current_trap_cx() -> &'static mut TrapContext
Expand description
Get the mutable reference to trap context of current task
-
\ No newline at end of file
+current_trap_cx in os::task - Rust Function os::task::current_trap_cx
source · pub fn current_trap_cx() -> &'static mut TrapContext
Expand description
Get the mutable reference to trap context of current task
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.current_user_token.html b/ch5/os/task/fn.current_user_token.html
index 6f11a2a3..66e6c27a 100644
--- a/ch5/os/task/fn.current_user_token.html
+++ b/ch5/os/task/fn.current_user_token.html
@@ -1,2 +1,2 @@
-current_user_token in os::task - Rust
\ No newline at end of file
+current_user_token in os::task - Rust Function os::task::current_user_token
source · pub fn current_user_token() -> usize
Expand description
Get token of the address space of current task
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.exit_current_and_run_next.html b/ch5/os/task/fn.exit_current_and_run_next.html
index a39c486f..7d16b005 100644
--- a/ch5/os/task/fn.exit_current_and_run_next.html
+++ b/ch5/os/task/fn.exit_current_and_run_next.html
@@ -1,2 +1,2 @@
-exit_current_and_run_next in os::task - Rust
\ No newline at end of file
+exit_current_and_run_next in os::task - Rust Function os::task::exit_current_and_run_next
source · pub fn exit_current_and_run_next(exit_code: i32)
Expand description
Exit the current ‘Running’ task and run the next task in task list.
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.fetch_task.html b/ch5/os/task/fn.fetch_task.html
index 1bd0282c..2d27aa7c 100644
--- a/ch5/os/task/fn.fetch_task.html
+++ b/ch5/os/task/fn.fetch_task.html
@@ -1,2 +1,2 @@
-fetch_task in os::task - Rust Function os::task::fetch_task
source · [−]pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Expand description
Interface offered to pop the first task
-
\ No newline at end of file
+fetch_task in os::task - Rust Function os::task::fetch_task
source · pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Expand description
Interface offered to pop the first task
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.pid_alloc.html b/ch5/os/task/fn.pid_alloc.html
index 65d909c0..4cf1a968 100644
--- a/ch5/os/task/fn.pid_alloc.html
+++ b/ch5/os/task/fn.pid_alloc.html
@@ -1,2 +1,2 @@
-pid_alloc in os::task - Rust
\ No newline at end of file
+pid_alloc in os::task - Rust
\ No newline at end of file
diff --git a/ch5/os/task/fn.run_tasks.html b/ch5/os/task/fn.run_tasks.html
index c6e96d8c..fde15911 100644
--- a/ch5/os/task/fn.run_tasks.html
+++ b/ch5/os/task/fn.run_tasks.html
@@ -1,3 +1,3 @@
-run_tasks in os::task - Rust pub fn run_tasks()
Expand description
The main part of process execution and scheduling
+
run_tasks in os::task - Rust
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.schedule.html b/ch5/os/task/fn.schedule.html
index 25b4a0f6..142ea291 100644
--- a/ch5/os/task/fn.schedule.html
+++ b/ch5/os/task/fn.schedule.html
@@ -1,2 +1,2 @@
-schedule in os::task - Rust
\ No newline at end of file
+schedule in os::task - Rust
\ No newline at end of file
diff --git a/ch5/os/task/fn.suspend_current_and_run_next.html b/ch5/os/task/fn.suspend_current_and_run_next.html
index cfc0db65..eba067ba 100644
--- a/ch5/os/task/fn.suspend_current_and_run_next.html
+++ b/ch5/os/task/fn.suspend_current_and_run_next.html
@@ -1,2 +1,2 @@
-suspend_current_and_run_next in os::task - Rust Function os::task::suspend_current_and_run_next
source · [−]pub fn suspend_current_and_run_next()
Expand description
Suspend the current ‘Running’ task and run the next task in task list.
-
\ No newline at end of file
+suspend_current_and_run_next in os::task - Rust Function os::task::suspend_current_and_run_next
source · pub fn suspend_current_and_run_next()
Expand description
Suspend the current ‘Running’ task and run the next task in task list.
+
\ No newline at end of file
diff --git a/ch5/os/task/fn.take_current_task.html b/ch5/os/task/fn.take_current_task.html
index c3317f4d..c8466f8a 100644
--- a/ch5/os/task/fn.take_current_task.html
+++ b/ch5/os/task/fn.take_current_task.html
@@ -1,2 +1,2 @@
-take_current_task in os::task - Rust Function os::task::take_current_task
source · [−]pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Take the current task,leaving a None in its place
-
\ No newline at end of file
+take_current_task in os::task - Rust Function os::task::take_current_task
source · pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Take the current task,leaving a None in its place
+
\ No newline at end of file
diff --git a/ch5/os/task/index.html b/ch5/os/task/index.html
index d0fc8917..00b8014a 100644
--- a/ch5/os/task/index.html
+++ b/ch5/os/task/index.html
@@ -1,39 +1,13 @@
-os::task - Rust Expand description
Task management implementation
+os::task - Rust Expand description
Task management implementation
Everything about task management, like starting and switching tasks is
implemented here.
-A single global instance of TaskManager
called TASK_MANAGER
controls
+
A single global instance of TaskManager
called TASK_MANAGER
controls
all the tasks in the whole operating system.
-A single global instance of Processor
called PROCESSOR
monitors running
+
A single global instance of Processor
called PROCESSOR
monitors running
task(s) for each core.
-A single global instance of PidAllocator
called PID_ALLOCATOR
allocates
+
A single global instance of PidAllocator
called PID_ALLOCATOR
allocates
pid for user apps.
Be careful when you see __switch
ASM function in switch.S
. Control flow around this function
might not be what you expect.
-Modules
context 🔒 Implementation of TaskContext
-manager 🔒 Implementation of TaskManager
-pid 🔒 Implementation of PidAllocator
-switch 🔒 Wrap switch.S
as a function
-task 🔒 Implementation of TaskControlBlock
-Structs
Globle process that init user shell
-Kernelstack for app
-Pid Allocator struct
-Bind pid lifetime to PidHandle
-Processor management structure
-task context structure containing some registers
-A array of TaskControlBlock
that is thread-safe
-Constants
pid of usertests app in make run TEST=1
-Functions
Add init process to the manager
-Interface offered to add task
-Get running task
-Get the mutable reference to trap context of current task
-Get token of the address space of current task
-Exit the current ‘Running’ task and run the next task in task list.
-Interface offered to pop the first task
-Allocate a pid from PID_ALLOCATOR
-The main part of process execution and scheduling
-Loop fetch_task
to get the process that needs to run, and switch the process through __switch
-Return to idle control flow for new scheduling
-Suspend the current ‘Running’ task and run the next task in task list.
-Take the current task,leaving a None in its place
-
\ No newline at end of file
+Modules
- context 🔒 Implementation of
TaskContext
- manager 🔒 Implementation of
TaskManager
- pid 🔒 Implementation of
PidAllocator
- Implementation of
Processor
and Intersection of control flow - switch 🔒 Wrap
switch.S
as a function - task 🔒 Implementation of
TaskControlBlock
Structs
- Globle process that init user shell
- Kernelstack for app
- Pid Allocator struct
- Bind pid lifetime to
PidHandle
- Processor management structure
- task context structure containing some registers
- A array of
TaskControlBlock
that is thread-safe
Constants
- pid of usertests app in make run TEST=1
Functions
- Add init process to the manager
- Interface offered to add task
- Get running task
- Get the mutable reference to trap context of current task
- Get token of the address space of current task
- Exit the current ‘Running’ task and run the next task in task list.
- Interface offered to pop the first task
- Allocate a pid from PID_ALLOCATOR
- The main part of process execution and scheduling
+Loop
fetch_task
to get the process that needs to run, and switch the process through __switch
- Return to idle control flow for new scheduling
- Suspend the current ‘Running’ task and run the next task in task list.
- Take the current task,leaving a None in its place
\ No newline at end of file
diff --git a/ch5/os/task/manager/fn.add_task.html b/ch5/os/task/manager/fn.add_task.html
index 9ca54c1c..f101e4fc 100644
--- a/ch5/os/task/manager/fn.add_task.html
+++ b/ch5/os/task/manager/fn.add_task.html
@@ -1,2 +1,2 @@
-add_task in os::task::manager - Rust
\ No newline at end of file
+add_task in os::task::manager - Rust
\ No newline at end of file
diff --git a/ch5/os/task/manager/fn.fetch_task.html b/ch5/os/task/manager/fn.fetch_task.html
index 29c1cecc..080b520b 100644
--- a/ch5/os/task/manager/fn.fetch_task.html
+++ b/ch5/os/task/manager/fn.fetch_task.html
@@ -1,2 +1,2 @@
-fetch_task in os::task::manager - Rust pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Expand description
Interface offered to pop the first task
-
\ No newline at end of file
+fetch_task in os::task::manager - Rust Function os::task::manager::fetch_task
source · pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Expand description
Interface offered to pop the first task
+
\ No newline at end of file
diff --git a/ch5/os/task/manager/index.html b/ch5/os/task/manager/index.html
index 7d5b6c90..e3cf325f 100644
--- a/ch5/os/task/manager/index.html
+++ b/ch5/os/task/manager/index.html
@@ -1,5 +1,2 @@
-os::task::manager - Rust Expand description
Implementation of TaskManager
-Structs
A array of TaskControlBlock
that is thread-safe
-Functions
Interface offered to add task
-Interface offered to pop the first task
-
\ No newline at end of file
+os::task::manager - Rust Expand description
Implementation of TaskManager
+Structs
- A array of
TaskControlBlock
that is thread-safe
Functions
- Interface offered to add task
- Interface offered to pop the first task
\ No newline at end of file
diff --git a/ch5/os/task/manager/sidebar-items.js b/ch5/os/task/manager/sidebar-items.js
index 2d0e3134..4f27ad34 100644
--- a/ch5/os/task/manager/sidebar-items.js
+++ b/ch5/os/task/manager/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["add_task","Interface offered to add task"],["fetch_task","Interface offered to pop the first task"]],"struct":[["TASK_MANAGER",""],["TaskManager","A array of `TaskControlBlock` that is thread-safe"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["add_task","fetch_task"],"struct":["TASK_MANAGER","TaskManager"]};
\ No newline at end of file
diff --git a/ch5/os/task/manager/struct.TASK_MANAGER.html b/ch5/os/task/manager/struct.TASK_MANAGER.html
index f07eea1f..da7686f4 100644
--- a/ch5/os/task/manager/struct.TASK_MANAGER.html
+++ b/ch5/os/task/manager/struct.TASK_MANAGER.html
@@ -1,17 +1,14 @@
-TASK_MANAGER in os::task::manager - Rust pub struct TASK_MANAGER {
+TASK_MANAGER in os::task::manager - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<TaskManager>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for TASK_MANAGER
type Target = UPSafeCell<TaskManager>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<TaskManager>
Dereferences the value.
-sourceimpl LazyStatic for TASK_MANAGER
Auto Trait Implementations
impl RefUnwindSafe for TASK_MANAGER
impl Send for TASK_MANAGER
impl Sync for TASK_MANAGER
impl Unpin for TASK_MANAGER
impl UnwindSafe for TASK_MANAGER
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<TaskManager>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for TASK_MANAGER
§type Target = UPSafeCell<TaskManager>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<TaskManager>
Dereferences the value.source§impl LazyStatic for TASK_MANAGER
Auto Trait Implementations§
§impl RefUnwindSafe for TASK_MANAGER
§impl Send for TASK_MANAGER
§impl Sync for TASK_MANAGER
§impl Unpin for TASK_MANAGER
§impl UnwindSafe for TASK_MANAGER
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/manager/struct.TaskManager.html b/ch5/os/task/manager/struct.TaskManager.html
index 014a1596..e8518360 100644
--- a/ch5/os/task/manager/struct.TaskManager.html
+++ b/ch5/os/task/manager/struct.TaskManager.html
@@ -1,19 +1,18 @@
-TaskManager in os::task::manager - Rust pub struct TaskManager {
+TaskManager in os::task::manager - Rust Struct os::task::manager::TaskManager
source · pub struct TaskManager {
ready_queue: VecDeque<Arc<TaskControlBlock>>,
-}
Expand description
A array of TaskControlBlock
that is thread-safe
-Fields
ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations
sourceimpl TaskManager
A simple FIFO scheduler.
-Auto Trait Implementations
impl !RefUnwindSafe for TaskManager
impl Send for TaskManager
impl Sync for TaskManager
impl Unpin for TaskManager
impl !UnwindSafe for TaskManager
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
A array of TaskControlBlock
that is thread-safe
+Fields§
§ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations§
source§impl TaskManager
A simple FIFO scheduler.
+Auto Trait Implementations§
§impl !RefUnwindSafe for TaskManager
§impl Send for TaskManager
§impl Sync for TaskManager
§impl Unpin for TaskManager
§impl !UnwindSafe for TaskManager
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/pid/fn.kernel_stack_position.html b/ch5/os/task/pid/fn.kernel_stack_position.html
index 0791a2ae..05f462a2 100644
--- a/ch5/os/task/pid/fn.kernel_stack_position.html
+++ b/ch5/os/task/pid/fn.kernel_stack_position.html
@@ -1,2 +1,2 @@
-kernel_stack_position in os::task::pid - Rust
\ No newline at end of file
+kernel_stack_position in os::task::pid - Rust
\ No newline at end of file
diff --git a/ch5/os/task/pid/fn.pid_alloc.html b/ch5/os/task/pid/fn.pid_alloc.html
index fa88b162..8599352c 100644
--- a/ch5/os/task/pid/fn.pid_alloc.html
+++ b/ch5/os/task/pid/fn.pid_alloc.html
@@ -1,2 +1,2 @@
-pid_alloc in os::task::pid - Rust
\ No newline at end of file
+pid_alloc in os::task::pid - Rust
\ No newline at end of file
diff --git a/ch5/os/task/pid/index.html b/ch5/os/task/pid/index.html
index 5a2b65fd..80be16d4 100644
--- a/ch5/os/task/pid/index.html
+++ b/ch5/os/task/pid/index.html
@@ -1,7 +1,2 @@
-os::task::pid - Rust Expand description
Implementation of PidAllocator
-Structs
Kernelstack for app
-Pid Allocator struct
-Bind pid lifetime to PidHandle
-Functions
Return (bottom, top) of a kernel stack in kernel space.
-Allocate a pid from PID_ALLOCATOR
-
\ No newline at end of file
+os::task::pid - Rust Expand description
Implementation of PidAllocator
+Structs
- Kernelstack for app
- Pid Allocator struct
- Bind pid lifetime to
PidHandle
Functions
- Return (bottom, top) of a kernel stack in kernel space.
- Allocate a pid from PID_ALLOCATOR
\ No newline at end of file
diff --git a/ch5/os/task/pid/sidebar-items.js b/ch5/os/task/pid/sidebar-items.js
index 836f33e0..8392d298 100644
--- a/ch5/os/task/pid/sidebar-items.js
+++ b/ch5/os/task/pid/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["kernel_stack_position","Return (bottom, top) of a kernel stack in kernel space."],["pid_alloc","Allocate a pid from PID_ALLOCATOR"]],"struct":[["KernelStack","Kernelstack for app"],["PID_ALLOCATOR",""],["PidAllocator","Pid Allocator struct"],["PidHandle","Bind pid lifetime to `PidHandle`"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["kernel_stack_position","pid_alloc"],"struct":["KernelStack","PID_ALLOCATOR","PidAllocator","PidHandle"]};
\ No newline at end of file
diff --git a/ch5/os/task/pid/struct.KernelStack.html b/ch5/os/task/pid/struct.KernelStack.html
index a1bb31ae..afa40ac9 100644
--- a/ch5/os/task/pid/struct.KernelStack.html
+++ b/ch5/os/task/pid/struct.KernelStack.html
@@ -1,19 +1,18 @@
-KernelStack in os::task::pid - Rust pub struct KernelStack {
+KernelStack in os::task::pid - Rust Expand description
Kernelstack for app
-Fields
pid: usize
Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for KernelStack
impl Send for KernelStack
impl Sync for KernelStack
impl Unpin for KernelStack
impl UnwindSafe for KernelStack
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Kernelstack for app
+Fields§
§pid: usize
Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for KernelStack
§impl Send for KernelStack
§impl Sync for KernelStack
§impl Unpin for KernelStack
§impl UnwindSafe for KernelStack
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/pid/struct.PID_ALLOCATOR.html b/ch5/os/task/pid/struct.PID_ALLOCATOR.html
index 56acccbb..8c81702f 100644
--- a/ch5/os/task/pid/struct.PID_ALLOCATOR.html
+++ b/ch5/os/task/pid/struct.PID_ALLOCATOR.html
@@ -1,17 +1,14 @@
-PID_ALLOCATOR in os::task::pid - Rust pub struct PID_ALLOCATOR {
+PID_ALLOCATOR in os::task::pid - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<PidAllocator>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for PID_ALLOCATOR
type Target = UPSafeCell<PidAllocator>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<PidAllocator>
Dereferences the value.
-sourceimpl LazyStatic for PID_ALLOCATOR
Auto Trait Implementations
impl RefUnwindSafe for PID_ALLOCATOR
impl Send for PID_ALLOCATOR
impl Sync for PID_ALLOCATOR
impl Unpin for PID_ALLOCATOR
impl UnwindSafe for PID_ALLOCATOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<PidAllocator>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for PID_ALLOCATOR
§type Target = UPSafeCell<PidAllocator>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<PidAllocator>
Dereferences the value.source§impl LazyStatic for PID_ALLOCATOR
Auto Trait Implementations§
§impl RefUnwindSafe for PID_ALLOCATOR
§impl Send for PID_ALLOCATOR
§impl Sync for PID_ALLOCATOR
§impl Unpin for PID_ALLOCATOR
§impl UnwindSafe for PID_ALLOCATOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/pid/struct.PidAllocator.html b/ch5/os/task/pid/struct.PidAllocator.html
index 34d376a7..1b4855a4 100644
--- a/ch5/os/task/pid/struct.PidAllocator.html
+++ b/ch5/os/task/pid/struct.PidAllocator.html
@@ -1,19 +1,18 @@
-PidAllocator in os::task::pid - Rust pub struct PidAllocator {
+PidAllocator in os::task::pid - Rust Struct os::task::pid::PidAllocator
source · pub struct PidAllocator {
current: usize,
recycled: Vec<usize>,
-}
Expand description
Pid Allocator struct
-Fields
current: usize
recycled: Vec<usize>
Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidAllocator
impl Send for PidAllocator
impl Sync for PidAllocator
impl Unpin for PidAllocator
impl UnwindSafe for PidAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Pid Allocator struct
+Fields§
§current: usize
§recycled: Vec<usize>
Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidAllocator
§impl Send for PidAllocator
§impl Sync for PidAllocator
§impl Unpin for PidAllocator
§impl UnwindSafe for PidAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/pid/struct.PidHandle.html b/ch5/os/task/pid/struct.PidHandle.html
index fcbe37fe..2f41be36 100644
--- a/ch5/os/task/pid/struct.PidHandle.html
+++ b/ch5/os/task/pid/struct.PidHandle.html
@@ -1,14 +1,12 @@
-PidHandle in os::task::pid - Rust pub struct PidHandle(pub usize);
Expand description
Bind pid lifetime to PidHandle
-Tuple Fields
0: usize
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidHandle
impl Send for PidHandle
impl Sync for PidHandle
impl Unpin for PidHandle
impl UnwindSafe for PidHandle
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+PidHandle in os::task::pid - Rust pub struct PidHandle(pub usize);
Expand description
Bind pid lifetime to PidHandle
+Tuple Fields§
§0: usize
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidHandle
§impl Send for PidHandle
§impl Sync for PidHandle
§impl Unpin for PidHandle
§impl UnwindSafe for PidHandle
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.current_task.html b/ch5/os/task/processor/fn.current_task.html
index 0ad442d8..b89ecbb4 100644
--- a/ch5/os/task/processor/fn.current_task.html
+++ b/ch5/os/task/processor/fn.current_task.html
@@ -1,2 +1,2 @@
-current_task in os::task::processor - Rust pub fn current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Get running task
-
\ No newline at end of file
+current_task in os::task::processor - Rust Function os::task::processor::current_task
source · pub fn current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Get running task
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.current_trap_cx.html b/ch5/os/task/processor/fn.current_trap_cx.html
index 079ed8f8..2c0ef498 100644
--- a/ch5/os/task/processor/fn.current_trap_cx.html
+++ b/ch5/os/task/processor/fn.current_trap_cx.html
@@ -1,2 +1,2 @@
-current_trap_cx in os::task::processor - Rust pub fn current_trap_cx() -> &'static mut TrapContext
Expand description
Get the mutable reference to trap context of current task
-
\ No newline at end of file
+current_trap_cx in os::task::processor - Rust Function os::task::processor::current_trap_cx
source · pub fn current_trap_cx() -> &'static mut TrapContext
Expand description
Get the mutable reference to trap context of current task
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.current_user_token.html b/ch5/os/task/processor/fn.current_user_token.html
index 30866e32..61122ac5 100644
--- a/ch5/os/task/processor/fn.current_user_token.html
+++ b/ch5/os/task/processor/fn.current_user_token.html
@@ -1,2 +1,2 @@
-current_user_token in os::task::processor - Rust
\ No newline at end of file
+current_user_token in os::task::processor - Rust
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.run_tasks.html b/ch5/os/task/processor/fn.run_tasks.html
index 0c1ba19b..d8a6d6cc 100644
--- a/ch5/os/task/processor/fn.run_tasks.html
+++ b/ch5/os/task/processor/fn.run_tasks.html
@@ -1,3 +1,3 @@
-run_tasks in os::task::processor - Rust pub fn run_tasks()
Expand description
The main part of process execution and scheduling
+
run_tasks in os::task::processor - Rust
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.schedule.html b/ch5/os/task/processor/fn.schedule.html
index bc208326..02470d31 100644
--- a/ch5/os/task/processor/fn.schedule.html
+++ b/ch5/os/task/processor/fn.schedule.html
@@ -1,2 +1,2 @@
-schedule in os::task::processor - Rust
\ No newline at end of file
+schedule in os::task::processor - Rust
\ No newline at end of file
diff --git a/ch5/os/task/processor/fn.take_current_task.html b/ch5/os/task/processor/fn.take_current_task.html
index 51be80b1..8545c8cf 100644
--- a/ch5/os/task/processor/fn.take_current_task.html
+++ b/ch5/os/task/processor/fn.take_current_task.html
@@ -1,2 +1,2 @@
-take_current_task in os::task::processor - Rust pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Take the current task,leaving a None in its place
-
\ No newline at end of file
+take_current_task in os::task::processor - Rust Function os::task::processor::take_current_task
source · pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Expand description
Take the current task,leaving a None in its place
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/index.html b/ch5/os/task/processor/index.html
index 5b40bae6..ed6018f8 100644
--- a/ch5/os/task/processor/index.html
+++ b/ch5/os/task/processor/index.html
@@ -1,10 +1,3 @@
-os::task::processor - Rust Expand description
Implementation of Processor
and Intersection of control flow
-Structs
Functions
Get running task
-Get the mutable reference to trap context of current task
-Get token of the address space of current task
-The main part of process execution and scheduling
-Loop fetch_task
to get the process that needs to run, and switch the process through __switch
-Return to idle control flow for new scheduling
-Take the current task,leaving a None in its place
-
\ No newline at end of file
+os::task::processor - Rust Expand description
Implementation of Processor
and Intersection of control flow
+Structs
- Processor management structure
Functions
- Get running task
- Get the mutable reference to trap context of current task
- Get token of the address space of current task
- The main part of process execution and scheduling
+Loop
fetch_task
to get the process that needs to run, and switch the process through __switch
- Return to idle control flow for new scheduling
- Take the current task,leaving a None in its place
\ No newline at end of file
diff --git a/ch5/os/task/processor/sidebar-items.js b/ch5/os/task/processor/sidebar-items.js
index b6e62833..567a9a18 100644
--- a/ch5/os/task/processor/sidebar-items.js
+++ b/ch5/os/task/processor/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["current_task","Get running task"],["current_trap_cx","Get the mutable reference to trap context of current task"],["current_user_token","Get token of the address space of current task"],["run_tasks","The main part of process execution and scheduling Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`"],["schedule","Return to idle control flow for new scheduling"],["take_current_task","Take the current task,leaving a None in its place"]],"struct":[["PROCESSOR",""],["Processor","Processor management structure"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["current_task","current_trap_cx","current_user_token","run_tasks","schedule","take_current_task"],"struct":["PROCESSOR","Processor"]};
\ No newline at end of file
diff --git a/ch5/os/task/processor/struct.PROCESSOR.html b/ch5/os/task/processor/struct.PROCESSOR.html
index 6e1ac655..37b4b4fc 100644
--- a/ch5/os/task/processor/struct.PROCESSOR.html
+++ b/ch5/os/task/processor/struct.PROCESSOR.html
@@ -1,17 +1,14 @@
-PROCESSOR in os::task::processor - Rust pub struct PROCESSOR {
+PROCESSOR in os::task::processor - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<Processor>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for PROCESSOR
type Target = UPSafeCell<Processor>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<Processor>
Dereferences the value.
-sourceimpl LazyStatic for PROCESSOR
Auto Trait Implementations
impl RefUnwindSafe for PROCESSOR
impl Send for PROCESSOR
impl Sync for PROCESSOR
impl Unpin for PROCESSOR
impl UnwindSafe for PROCESSOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<Processor>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for PROCESSOR
§type Target = UPSafeCell<Processor>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<Processor>
Dereferences the value.source§impl LazyStatic for PROCESSOR
Auto Trait Implementations§
§impl RefUnwindSafe for PROCESSOR
§impl Send for PROCESSOR
§impl Sync for PROCESSOR
§impl Unpin for PROCESSOR
§impl UnwindSafe for PROCESSOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/processor/struct.Processor.html b/ch5/os/task/processor/struct.Processor.html
index 4e5e909b..fd743a7d 100644
--- a/ch5/os/task/processor/struct.Processor.html
+++ b/ch5/os/task/processor/struct.Processor.html
@@ -1,22 +1,21 @@
-Processor in os::task::processor - Rust pub struct Processor {
+Processor in os::task::processor - Rust pub struct Processor {
current: Option<Arc<TaskControlBlock>>,
idle_task_cx: TaskContext,
-}
Expand description
Processor management structure
-Fields
current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
-idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
-Implementations
sourceimpl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
-sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
-sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
-Auto Trait Implementations
impl !RefUnwindSafe for Processor
impl Send for Processor
impl Sync for Processor
impl Unpin for Processor
impl !UnwindSafe for Processor
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Processor management structure
+Fields§
§current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
+§idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
+Implementations§
source§impl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
+sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
+sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
+Auto Trait Implementations§
§impl !RefUnwindSafe for Processor
§impl Send for Processor
§impl Sync for Processor
§impl Unpin for Processor
§impl !UnwindSafe for Processor
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/sidebar-items.js b/ch5/os/task/sidebar-items.js
index c1b4a81b..d5317e17 100644
--- a/ch5/os/task/sidebar-items.js
+++ b/ch5/os/task/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"constant":[["IDLE_PID","pid of usertests app in make run TEST=1"]],"fn":[["add_initproc","Add init process to the manager"],["add_task","Interface offered to add task"],["current_task","Get running task"],["current_trap_cx","Get the mutable reference to trap context of current task"],["current_user_token","Get token of the address space of current task"],["exit_current_and_run_next","Exit the current ‘Running’ task and run the next task in task list."],["fetch_task","Interface offered to pop the first task"],["pid_alloc","Allocate a pid from PID_ALLOCATOR"],["run_tasks","The main part of process execution and scheduling Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`"],["schedule","Return to idle control flow for new scheduling"],["suspend_current_and_run_next","Suspend the current ‘Running’ task and run the next task in task list."],["take_current_task","Take the current task,leaving a None in its place"]],"mod":[["context","Implementation of [`TaskContext`]"],["manager","Implementation of [`TaskManager`]"],["pid","Implementation of [`PidAllocator`]"],["processor","Implementation of [`Processor`] and Intersection of control flow"],["switch","Wrap `switch.S` as a function"],["task","Implementation of [`TaskControlBlock`]"]],"struct":[["INITPROC","Globle process that init user shell"],["KernelStack","Kernelstack for app"],["PidAllocator","Pid Allocator struct"],["PidHandle","Bind pid lifetime to `PidHandle`"],["Processor","Processor management structure"],["TaskContext","task context structure containing some registers"],["TaskManager","A array of `TaskControlBlock` that is thread-safe"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"constant":["IDLE_PID"],"fn":["add_initproc","add_task","current_task","current_trap_cx","current_user_token","exit_current_and_run_next","fetch_task","pid_alloc","run_tasks","schedule","suspend_current_and_run_next","take_current_task"],"mod":["context","manager","pid","processor","switch","task"],"struct":["INITPROC","KernelStack","PidAllocator","PidHandle","Processor","TaskContext","TaskManager"]};
\ No newline at end of file
diff --git a/ch5/os/task/struct.INITPROC.html b/ch5/os/task/struct.INITPROC.html
index 371e8a66..78f862b3 100644
--- a/ch5/os/task/struct.INITPROC.html
+++ b/ch5/os/task/struct.INITPROC.html
@@ -1,17 +1,14 @@
-INITPROC in os::task - Rust pub struct INITPROC {
+INITPROC in os::task - Rust Expand description
Globle process that init user shell
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for INITPROC
type Target = Arc<TaskControlBlock>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<TaskControlBlock>
Dereferences the value.
-sourceimpl LazyStatic for INITPROC
Auto Trait Implementations
impl RefUnwindSafe for INITPROC
impl Send for INITPROC
impl Sync for INITPROC
impl Unpin for INITPROC
impl UnwindSafe for INITPROC
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Globle process that init user shell
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for INITPROC
§type Target = Arc<TaskControlBlock, Global>
The resulting type after dereferencing.source§fn deref(&self) -> &Arc<TaskControlBlock>
Dereferences the value.source§impl LazyStatic for INITPROC
Auto Trait Implementations§
§impl RefUnwindSafe for INITPROC
§impl Send for INITPROC
§impl Sync for INITPROC
§impl Unpin for INITPROC
§impl UnwindSafe for INITPROC
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.KernelStack.html b/ch5/os/task/struct.KernelStack.html
index ab970faa..3d4f1c11 100644
--- a/ch5/os/task/struct.KernelStack.html
+++ b/ch5/os/task/struct.KernelStack.html
@@ -1,19 +1,18 @@
-KernelStack in os::task - Rust Struct os::task::KernelStack
source · [−]pub struct KernelStack {
+KernelStack in os::task - Rust Struct os::task::KernelStack
source · pub struct KernelStack {
pid: usize,
-}
Expand description
Kernelstack for app
-Fields
pid: usize
Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for KernelStack
impl Send for KernelStack
impl Sync for KernelStack
impl Unpin for KernelStack
impl UnwindSafe for KernelStack
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Kernelstack for app
+Fields§
§pid: usize
Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for KernelStack
§impl Send for KernelStack
§impl Sync for KernelStack
§impl Unpin for KernelStack
§impl UnwindSafe for KernelStack
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.PidAllocator.html b/ch5/os/task/struct.PidAllocator.html
index 8d2eb107..e00c1cc6 100644
--- a/ch5/os/task/struct.PidAllocator.html
+++ b/ch5/os/task/struct.PidAllocator.html
@@ -1,19 +1,18 @@
-PidAllocator in os::task - Rust Struct os::task::PidAllocator
source · [−]pub struct PidAllocator {
+PidAllocator in os::task - Rust Struct os::task::PidAllocator
source · pub struct PidAllocator {
current: usize,
recycled: Vec<usize>,
-}
Expand description
Pid Allocator struct
-Fields
current: usize
recycled: Vec<usize>
Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidAllocator
impl Send for PidAllocator
impl Sync for PidAllocator
impl Unpin for PidAllocator
impl UnwindSafe for PidAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Pid Allocator struct
+Fields§
§current: usize
§recycled: Vec<usize>
Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidAllocator
§impl Send for PidAllocator
§impl Sync for PidAllocator
§impl Unpin for PidAllocator
§impl UnwindSafe for PidAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.PidHandle.html b/ch5/os/task/struct.PidHandle.html
index 9450fa6e..cc55ffe7 100644
--- a/ch5/os/task/struct.PidHandle.html
+++ b/ch5/os/task/struct.PidHandle.html
@@ -1,14 +1,12 @@
-PidHandle in os::task - Rust pub struct PidHandle(pub usize);
Expand description
Bind pid lifetime to PidHandle
-Tuple Fields
0: usize
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidHandle
impl Send for PidHandle
impl Sync for PidHandle
impl Unpin for PidHandle
impl UnwindSafe for PidHandle
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+PidHandle in os::task - Rust pub struct PidHandle(pub usize);
Expand description
Bind pid lifetime to PidHandle
+Tuple Fields§
§0: usize
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidHandle
§impl Send for PidHandle
§impl Sync for PidHandle
§impl Unpin for PidHandle
§impl UnwindSafe for PidHandle
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.Processor.html b/ch5/os/task/struct.Processor.html
index 30d3c8ed..b982e912 100644
--- a/ch5/os/task/struct.Processor.html
+++ b/ch5/os/task/struct.Processor.html
@@ -1,22 +1,21 @@
-Processor in os::task - Rust pub struct Processor {
+Processor in os::task - Rust pub struct Processor {
current: Option<Arc<TaskControlBlock>>,
idle_task_cx: TaskContext,
-}
Expand description
Processor management structure
-Fields
current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
-idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
-Implementations
sourceimpl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
-sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
-sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
-Auto Trait Implementations
impl !RefUnwindSafe for Processor
impl Send for Processor
impl Sync for Processor
impl Unpin for Processor
impl !UnwindSafe for Processor
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Processor management structure
+Fields§
§current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
+§idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
+Implementations§
source§impl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
+sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
+sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
+Auto Trait Implementations§
§impl !RefUnwindSafe for Processor
§impl Send for Processor
§impl Sync for Processor
§impl Unpin for Processor
§impl !UnwindSafe for Processor
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.TaskContext.html b/ch5/os/task/struct.TaskContext.html
index 3648e800..67729232 100644
--- a/ch5/os/task/struct.TaskContext.html
+++ b/ch5/os/task/struct.TaskContext.html
@@ -1,22 +1,21 @@
-TaskContext in os::task - Rust Struct os::task::TaskContext
source · [−]#[repr(C)]pub struct TaskContext {
+TaskContext in os::task - Rust Struct os::task::TaskContext
source · #[repr(C)]pub struct TaskContext {
ra: usize,
sp: usize,
- s: [usize; 12],
-}
Expand description
task context structure containing some registers
-Fields
ra: usize
return address ( e.g. __restore ) of __switch ASM function
-sp: usize
kernel stack pointer of app
-s: [usize; 12]
s0-11 register, callee saved
-Implementations
sourceimpl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
-Auto Trait Implementations
impl RefUnwindSafe for TaskContext
impl Send for TaskContext
impl Sync for TaskContext
impl Unpin for TaskContext
impl UnwindSafe for TaskContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+ s: [usize; 12],
+}Expand description
task context structure containing some registers
+Fields§
§ra: usize
return address ( e.g. __restore ) of __switch ASM function
+§sp: usize
kernel stack pointer of app
+§s: [usize; 12]
s0-11 register, callee saved
+Implementations§
source§impl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+Auto Trait Implementations§
§impl RefUnwindSafe for TaskContext
§impl Send for TaskContext
§impl Sync for TaskContext
§impl Unpin for TaskContext
§impl UnwindSafe for TaskContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/struct.TaskManager.html b/ch5/os/task/struct.TaskManager.html
index d5c6e460..a904b98f 100644
--- a/ch5/os/task/struct.TaskManager.html
+++ b/ch5/os/task/struct.TaskManager.html
@@ -1,19 +1,18 @@
-TaskManager in os::task - Rust Struct os::task::TaskManager
source · [−]pub struct TaskManager {
+TaskManager in os::task - Rust Struct os::task::TaskManager
source · pub struct TaskManager {
ready_queue: VecDeque<Arc<TaskControlBlock>>,
-}
Expand description
A array of TaskControlBlock
that is thread-safe
-Fields
ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations
sourceimpl TaskManager
A simple FIFO scheduler.
-Auto Trait Implementations
impl !RefUnwindSafe for TaskManager
impl Send for TaskManager
impl Sync for TaskManager
impl Unpin for TaskManager
impl !UnwindSafe for TaskManager
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
A array of TaskControlBlock
that is thread-safe
+Fields§
§ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations§
source§impl TaskManager
A simple FIFO scheduler.
+Auto Trait Implementations§
§impl !RefUnwindSafe for TaskManager
§impl Send for TaskManager
§impl Sync for TaskManager
§impl Unpin for TaskManager
§impl !UnwindSafe for TaskManager
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/switch/fn.__switch.html b/ch5/os/task/switch/fn.__switch.html
index f6de6956..fe2ca3b4 100644
--- a/ch5/os/task/switch/fn.__switch.html
+++ b/ch5/os/task/switch/fn.__switch.html
@@ -1 +1,4 @@
-__switch in os::task::switch - Rust pub unsafe extern "C" fn __switch(
current_task_cx_ptr: *mut TaskContext,
next_task_cx_ptr: *const TaskContext
)
\ No newline at end of file
+__switch in os::task::switch - Rust pub unsafe extern "C" fn __switch(
+ current_task_cx_ptr: *mut TaskContext,
+ next_task_cx_ptr: *const TaskContext
+)
\ No newline at end of file
diff --git a/ch5/os/task/switch/index.html b/ch5/os/task/switch/index.html
index 5d71f760..a5a5f151 100644
--- a/ch5/os/task/switch/index.html
+++ b/ch5/os/task/switch/index.html
@@ -1,2 +1,2 @@
-os::task::switch - Rust
\ No newline at end of file
+os::task::switch - Rust
\ No newline at end of file
diff --git a/ch5/os/task/switch/sidebar-items.js b/ch5/os/task/switch/sidebar-items.js
index 28ba182b..8dea751a 100644
--- a/ch5/os/task/switch/sidebar-items.js
+++ b/ch5/os/task/switch/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["__switch",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["__switch"]};
\ No newline at end of file
diff --git a/ch5/os/task/task/enum.TaskStatus.html b/ch5/os/task/task/enum.TaskStatus.html
index 320d4d1f..a18af3f8 100644
--- a/ch5/os/task/task/enum.TaskStatus.html
+++ b/ch5/os/task/task/enum.TaskStatus.html
@@ -1,24 +1,18 @@
-TaskStatus in os::task::task - Rust pub enum TaskStatus {
+TaskStatus in os::task::task - Rust Enum os::task::task::TaskStatus
source · pub enum TaskStatus {
Ready,
Running,
Zombie,
-}
Variants
Ready
Running
Zombie
Trait Implementations
sourceimpl Clone for TaskStatus
sourcefn clone(&self) -> TaskStatus
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl PartialEq<TaskStatus> for TaskStatus
sourceimpl Copy for TaskStatus
sourceimpl StructuralPartialEq for TaskStatus
Auto Trait Implementations
impl RefUnwindSafe for TaskStatus
impl Send for TaskStatus
impl Sync for TaskStatus
impl Unpin for TaskStatus
impl UnwindSafe for TaskStatus
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Variants§
Trait Implementations§
source§impl Clone for TaskStatus
source§fn clone(&self) -> TaskStatus
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl PartialEq<TaskStatus> for TaskStatus
source§fn eq(&self, other: &TaskStatus) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl Copy for TaskStatus
source§impl StructuralPartialEq for TaskStatus
Auto Trait Implementations§
§impl RefUnwindSafe for TaskStatus
§impl Send for TaskStatus
§impl Sync for TaskStatus
§impl Unpin for TaskStatus
§impl UnwindSafe for TaskStatus
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/task/index.html b/ch5/os/task/task/index.html
index e4431382..f1aac1f7 100644
--- a/ch5/os/task/task/index.html
+++ b/ch5/os/task/task/index.html
@@ -1,2 +1,2 @@
-os::task::task - Rust Expand description
Implementation of TaskControlBlock
-Structs
Enums
\ No newline at end of file
+os::task::task - Rust Expand description
Implementation of TaskControlBlock
+Structs
Enums
\ No newline at end of file
diff --git a/ch5/os/task/task/sidebar-items.js b/ch5/os/task/task/sidebar-items.js
index 272090ba..e3e27912 100644
--- a/ch5/os/task/task/sidebar-items.js
+++ b/ch5/os/task/task/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"enum":[["TaskStatus",""]],"struct":[["TaskControlBlock",""],["TaskControlBlockInner",""]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"enum":["TaskStatus"],"struct":["TaskControlBlock","TaskControlBlockInner"]};
\ No newline at end of file
diff --git a/ch5/os/task/task/struct.TaskControlBlock.html b/ch5/os/task/task/struct.TaskControlBlock.html
index 76b564d8..13111059 100644
--- a/ch5/os/task/task/struct.TaskControlBlock.html
+++ b/ch5/os/task/task/struct.TaskControlBlock.html
@@ -1,16 +1,15 @@
-TaskControlBlock in os::task::task - Rust pub struct TaskControlBlock {
+TaskControlBlock in os::task::task - Rust Struct os::task::task::TaskControlBlock
source · pub struct TaskControlBlock {
pub pid: PidHandle,
pub kernel_stack: KernelStack,
inner: UPSafeCell<TaskControlBlockInner>,
-}
Fields
pid: PidHandle
kernel_stack: KernelStack
inner: UPSafeCell<TaskControlBlockInner>
Implementations
Auto Trait Implementations
impl !RefUnwindSafe for TaskControlBlock
impl Send for TaskControlBlock
impl Sync for TaskControlBlock
impl Unpin for TaskControlBlock
impl !UnwindSafe for TaskControlBlock
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§pid: PidHandle
§kernel_stack: KernelStack
§inner: UPSafeCell<TaskControlBlockInner>
Implementations§
Auto Trait Implementations§
§impl !RefUnwindSafe for TaskControlBlock
§impl Send for TaskControlBlock
§impl Sync for TaskControlBlock
§impl Unpin for TaskControlBlock
§impl !UnwindSafe for TaskControlBlock
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/task/task/struct.TaskControlBlockInner.html b/ch5/os/task/task/struct.TaskControlBlockInner.html
index a3d5dc46..504d52df 100644
--- a/ch5/os/task/task/struct.TaskControlBlockInner.html
+++ b/ch5/os/task/task/struct.TaskControlBlockInner.html
@@ -1,4 +1,4 @@
-TaskControlBlockInner in os::task::task - Rust pub struct TaskControlBlockInner {
+TaskControlBlockInner in os::task::task - Rust Struct os::task::task::TaskControlBlockInner
source · pub struct TaskControlBlockInner {
pub trap_cx_ppn: PhysPageNum,
pub base_size: usize,
pub task_cx: TaskContext,
@@ -7,15 +7,14 @@
pub parent: Option<Weak<TaskControlBlock>>,
pub children: Vec<Arc<TaskControlBlock>>,
pub exit_code: i32,
-}
Fields
trap_cx_ppn: PhysPageNum
base_size: usize
task_cx: TaskContext
task_status: TaskStatus
memory_set: MemorySet
parent: Option<Weak<TaskControlBlock>>
children: Vec<Arc<TaskControlBlock>>
exit_code: i32
Implementations
sourceimpl TaskControlBlockInner
sourcepub fn get_trap_cx(&self) -> &'static mut TrapContext
sourcepub fn get_user_token(&self) -> usize
sourcefn get_status(&self) -> TaskStatus
sourcepub fn is_zombie(&self) -> bool
Auto Trait Implementations
impl !RefUnwindSafe for TaskControlBlockInner
impl Send for TaskControlBlockInner
impl Sync for TaskControlBlockInner
impl Unpin for TaskControlBlockInner
impl !UnwindSafe for TaskControlBlockInner
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§trap_cx_ppn: PhysPageNum
§base_size: usize
§task_cx: TaskContext
§task_status: TaskStatus
§memory_set: MemorySet
§parent: Option<Weak<TaskControlBlock>>
§children: Vec<Arc<TaskControlBlock>>
§exit_code: i32
Implementations§
source§impl TaskControlBlockInner
sourcepub fn get_trap_cx(&self) -> &'static mut TrapContext
sourcepub fn get_user_token(&self) -> usize
sourcefn get_status(&self) -> TaskStatus
sourcepub fn is_zombie(&self) -> bool
Auto Trait Implementations§
§impl !RefUnwindSafe for TaskControlBlockInner
§impl Send for TaskControlBlockInner
§impl Sync for TaskControlBlockInner
§impl Unpin for TaskControlBlockInner
§impl !UnwindSafe for TaskControlBlockInner
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/timer/constant.MSEC_PER_SEC.html b/ch5/os/timer/constant.MSEC_PER_SEC.html
index b225d5c1..38b28724 100644
--- a/ch5/os/timer/constant.MSEC_PER_SEC.html
+++ b/ch5/os/timer/constant.MSEC_PER_SEC.html
@@ -1 +1 @@
-MSEC_PER_SEC in os::timer - Rust
\ No newline at end of file
+MSEC_PER_SEC in os::timer - Rust Constant os::timer::MSEC_PER_SEC
source · const MSEC_PER_SEC: usize = 1000;
\ No newline at end of file
diff --git a/ch5/os/timer/constant.TICKS_PER_SEC.html b/ch5/os/timer/constant.TICKS_PER_SEC.html
index d61f9ec0..13cd686d 100644
--- a/ch5/os/timer/constant.TICKS_PER_SEC.html
+++ b/ch5/os/timer/constant.TICKS_PER_SEC.html
@@ -1 +1 @@
-TICKS_PER_SEC in os::timer - Rust
\ No newline at end of file
+TICKS_PER_SEC in os::timer - Rust Constant os::timer::TICKS_PER_SEC
source · const TICKS_PER_SEC: usize = 100;
\ No newline at end of file
diff --git a/ch5/os/timer/fn.get_time.html b/ch5/os/timer/fn.get_time.html
index 72baf358..824ae03f 100644
--- a/ch5/os/timer/fn.get_time.html
+++ b/ch5/os/timer/fn.get_time.html
@@ -1,2 +1,2 @@
-get_time in os::timer - Rust
\ No newline at end of file
+get_time in os::timer - Rust
\ No newline at end of file
diff --git a/ch5/os/timer/fn.get_time_ms.html b/ch5/os/timer/fn.get_time_ms.html
index 68e63c45..e6805486 100644
--- a/ch5/os/timer/fn.get_time_ms.html
+++ b/ch5/os/timer/fn.get_time_ms.html
@@ -1,2 +1,2 @@
-get_time_ms in os::timer - Rust
\ No newline at end of file
+get_time_ms in os::timer - Rust Function os::timer::get_time_ms
source · pub fn get_time_ms() -> usize
Expand description
get current time in microseconds
+
\ No newline at end of file
diff --git a/ch5/os/timer/fn.set_next_trigger.html b/ch5/os/timer/fn.set_next_trigger.html
index 8e504372..ae5c305c 100644
--- a/ch5/os/timer/fn.set_next_trigger.html
+++ b/ch5/os/timer/fn.set_next_trigger.html
@@ -1,2 +1,2 @@
-set_next_trigger in os::timer - Rust Function os::timer::set_next_trigger
source · [−]pub fn set_next_trigger()
Expand description
set the next timer interrupt
-
\ No newline at end of file
+set_next_trigger in os::timer - Rust Function os::timer::set_next_trigger
source · pub fn set_next_trigger()
Expand description
set the next timer interrupt
+
\ No newline at end of file
diff --git a/ch5/os/timer/index.html b/ch5/os/timer/index.html
index 5a0742df..3163dace 100644
--- a/ch5/os/timer/index.html
+++ b/ch5/os/timer/index.html
@@ -1,5 +1,2 @@
-os::timer - Rust
\ No newline at end of file
+os::timer - Rust
\ No newline at end of file
diff --git a/ch5/os/timer/sidebar-items.js b/ch5/os/timer/sidebar-items.js
index 0a4fc292..bf5ff37b 100644
--- a/ch5/os/timer/sidebar-items.js
+++ b/ch5/os/timer/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"constant":[["MSEC_PER_SEC",""],["TICKS_PER_SEC",""]],"fn":[["get_time","get current time"],["get_time_ms","get current time in microseconds"],["set_next_trigger","set the next timer interrupt"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"constant":["MSEC_PER_SEC","TICKS_PER_SEC"],"fn":["get_time","get_time_ms","set_next_trigger"]};
\ No newline at end of file
diff --git a/ch5/os/trap/context/index.html b/ch5/os/trap/context/index.html
index d8c3b3a5..2eb0a37d 100644
--- a/ch5/os/trap/context/index.html
+++ b/ch5/os/trap/context/index.html
@@ -1,3 +1,2 @@
-os::trap::context - Rust Expand description
Implementation of TrapContext
-Structs
trap context structure containing sstatus, sepc and registers
-
\ No newline at end of file
+os::trap::context - Rust Expand description
Implementation of TrapContext
+Structs
- trap context structure containing sstatus, sepc and registers
\ No newline at end of file
diff --git a/ch5/os/trap/context/sidebar-items.js b/ch5/os/trap/context/sidebar-items.js
index 2933c8a8..920f7c9e 100644
--- a/ch5/os/trap/context/sidebar-items.js
+++ b/ch5/os/trap/context/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"struct":[["TrapContext","trap context structure containing sstatus, sepc and registers"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"struct":["TrapContext"]};
\ No newline at end of file
diff --git a/ch5/os/trap/context/struct.TrapContext.html b/ch5/os/trap/context/struct.TrapContext.html
index 125f0b9f..4e1c34ac 100644
--- a/ch5/os/trap/context/struct.TrapContext.html
+++ b/ch5/os/trap/context/struct.TrapContext.html
@@ -1,28 +1,33 @@
-TrapContext in os::trap::context - Rust #[repr(C)]pub struct TrapContext {
- pub x: [usize; 32],
+TrapContext in os::trap::context - Rust Struct os::trap::context::TrapContext
source · #[repr(C)]pub struct TrapContext {
+ pub x: [usize; 32],
pub sstatus: Sstatus,
pub sepc: usize,
pub kernel_satp: usize,
pub kernel_sp: usize,
pub trap_handler: usize,
-}
Expand description
trap context structure containing sstatus, sepc and registers
-Fields
x: [usize; 32]
general regs[0..31]
-sstatus: Sstatus
CSR sstatus
-sepc: usize
CSR sepc
-kernel_satp: usize
Addr of Page Table
-kernel_sp: usize
kernel stack
-trap_handler: usize
Addr of trap_handler function
-Implementations
Auto Trait Implementations
impl RefUnwindSafe for TrapContext
impl Send for TrapContext
impl Sync for TrapContext
impl Unpin for TrapContext
impl UnwindSafe for TrapContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
trap context structure containing sstatus, sepc and registers
+Fields§
§x: [usize; 32]
general regs[0..31]
+§sstatus: Sstatus
CSR sstatus
+§sepc: usize
CSR sepc
+§kernel_satp: usize
Addr of Page Table
+§kernel_sp: usize
kernel stack
+§trap_handler: usize
Addr of trap_handler function
+Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for TrapContext
§impl Send for TrapContext
§impl Sync for TrapContext
§impl Unpin for TrapContext
§impl UnwindSafe for TrapContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/os/trap/fn.enable_timer_interrupt.html b/ch5/os/trap/fn.enable_timer_interrupt.html
index 8777adec..9f286f5c 100644
--- a/ch5/os/trap/fn.enable_timer_interrupt.html
+++ b/ch5/os/trap/fn.enable_timer_interrupt.html
@@ -1,2 +1,2 @@
-enable_timer_interrupt in os::trap - Rust Function os::trap::enable_timer_interrupt
source · [−]pub fn enable_timer_interrupt()
Expand description
enable timer interrupt in sie CSR
-
\ No newline at end of file
+enable_timer_interrupt in os::trap - Rust Function os::trap::enable_timer_interrupt
source · pub fn enable_timer_interrupt()
Expand description
enable timer interrupt in sie CSR
+
\ No newline at end of file
diff --git a/ch5/os/trap/fn.init.html b/ch5/os/trap/fn.init.html
index 58c7bd2f..4a472035 100644
--- a/ch5/os/trap/fn.init.html
+++ b/ch5/os/trap/fn.init.html
@@ -1,2 +1,2 @@
-init in os::trap - Rust
\ No newline at end of file
+init in os::trap - Rust
\ No newline at end of file
diff --git a/ch5/os/trap/fn.set_kernel_trap_entry.html b/ch5/os/trap/fn.set_kernel_trap_entry.html
index c92c8a41..601fb857 100644
--- a/ch5/os/trap/fn.set_kernel_trap_entry.html
+++ b/ch5/os/trap/fn.set_kernel_trap_entry.html
@@ -1 +1 @@
-set_kernel_trap_entry in os::trap - Rust Function os::trap::set_kernel_trap_entry
source · [−]fn set_kernel_trap_entry()
\ No newline at end of file
+set_kernel_trap_entry in os::trap - Rust Function os::trap::set_kernel_trap_entry
source · fn set_kernel_trap_entry()
\ No newline at end of file
diff --git a/ch5/os/trap/fn.set_user_trap_entry.html b/ch5/os/trap/fn.set_user_trap_entry.html
index 9c6f8ff1..5b3f1ca9 100644
--- a/ch5/os/trap/fn.set_user_trap_entry.html
+++ b/ch5/os/trap/fn.set_user_trap_entry.html
@@ -1 +1 @@
-set_user_trap_entry in os::trap - Rust Function os::trap::set_user_trap_entry
source · [−]fn set_user_trap_entry()
\ No newline at end of file
+set_user_trap_entry in os::trap - Rust Function os::trap::set_user_trap_entry
source · fn set_user_trap_entry()
\ No newline at end of file
diff --git a/ch5/os/trap/fn.trap_from_kernel.html b/ch5/os/trap/fn.trap_from_kernel.html
index 0a605f3c..b53abc14 100644
--- a/ch5/os/trap/fn.trap_from_kernel.html
+++ b/ch5/os/trap/fn.trap_from_kernel.html
@@ -1,4 +1,4 @@
-trap_from_kernel in os::trap - Rust Function os::trap::trap_from_kernel
source · [−]#[no_mangle]
-pub fn trap_from_kernel() -> !
Expand description
Unimplement: traps/interrupts/exceptions from kernel mode
+
trap_from_kernel in os::trap - Rust Function os::trap::trap_from_kernel
source · #[no_mangle]
+pub fn trap_from_kernel() -> !
Expand description
Unimplement: traps/interrupts/exceptions from kernel mode
Todo: Chapter 9: I/O device
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/os/trap/fn.trap_handler.html b/ch5/os/trap/fn.trap_handler.html
index a4784155..f05a5da7 100644
--- a/ch5/os/trap/fn.trap_handler.html
+++ b/ch5/os/trap/fn.trap_handler.html
@@ -1,3 +1,3 @@
-trap_handler in os::trap - Rust
\ No newline at end of file
+trap_handler in os::trap - Rust Function os::trap::trap_handler
source · #[no_mangle]
+pub fn trap_handler() -> !
Expand description
handle an interrupt, exception, or system call from user space
+
\ No newline at end of file
diff --git a/ch5/os/trap/fn.trap_return.html b/ch5/os/trap/fn.trap_return.html
index 79e65c6f..695a6ba0 100644
--- a/ch5/os/trap/fn.trap_return.html
+++ b/ch5/os/trap/fn.trap_return.html
@@ -1,5 +1,5 @@
-trap_return in os::trap - Rust Function os::trap::trap_return
source · [−]#[no_mangle]
-pub fn trap_return() -> !
Expand description
set the new addr of __restore asm function in TRAMPOLINE page,
+
trap_return in os::trap - Rust Function os::trap::trap_return
source · #[no_mangle]
+pub fn trap_return() -> !
Expand description
set the new addr of __restore asm function in TRAMPOLINE page,
set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
finally, jump to new addr of __restore asm function
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/os/trap/index.html b/ch5/os/trap/index.html
index 3a27b318..859d7749 100644
--- a/ch5/os/trap/index.html
+++ b/ch5/os/trap/index.html
@@ -1,21 +1,14 @@
-os::trap - Rust Expand description
Trap handling functionality
+os::trap - Rust Expand description
Trap handling functionality
For rCore, we have a single trap entry point, namely __alltraps
. At
-initialization in init()
, we set the stvec
CSR to point to it.
+initialization in init()
, we set the stvec
CSR to point to it.
All traps go through __alltraps
, which is defined in trap.S
. The
assembly language code does just enough work restore the kernel space
context, ensuring that Rust code safely runs, and transfers control to
-trap_handler()
.
+trap_handler()
.
It then calls different functionality based on what exactly the exception
was. For example, timer interrupts trigger task preemption, and syscalls go
-to syscall()
.
-Modules
context 🔒 Implementation of TrapContext
-Structs
trap context structure containing sstatus, sepc and registers
-Functions
enable timer interrupt in sie CSR
-initialize CSR stvec
as the entry of __alltraps
-Unimplement: traps/interrupts/exceptions from kernel mode
-Todo: Chapter 9: I/O device
-handle an interrupt, exception, or system call from user space
-set the new addr of __restore asm function in TRAMPOLINE page,
+to syscall()
.
+Modules
- context 🔒 Implementation of
TrapContext
Structs
- trap context structure containing sstatus, sepc and registers
Functions
- enable timer interrupt in sie CSR
- initialize CSR
stvec
as the entry of __alltraps
- Unimplement: traps/interrupts/exceptions from kernel mode
+Todo: Chapter 9: I/O device
- handle an interrupt, exception, or system call from user space
- set the new addr of __restore asm function in TRAMPOLINE page,
set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
-finally, jump to new addr of __restore asm function
-
\ No newline at end of file
+finally, jump to new addr of __restore asm function
\ No newline at end of file
diff --git a/ch5/os/trap/sidebar-items.js b/ch5/os/trap/sidebar-items.js
index ba94a4d1..0901c834 100644
--- a/ch5/os/trap/sidebar-items.js
+++ b/ch5/os/trap/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":[["enable_timer_interrupt","enable timer interrupt in sie CSR"],["init","initialize CSR `stvec` as the entry of `__alltraps`"],["set_kernel_trap_entry",""],["set_user_trap_entry",""],["trap_from_kernel","Unimplement: traps/interrupts/exceptions from kernel mode Todo: Chapter 9: I/O device"],["trap_handler","handle an interrupt, exception, or system call from user space"],["trap_return","set the new addr of __restore asm function in TRAMPOLINE page, set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table, finally, jump to new addr of __restore asm function"]],"mod":[["context","Implementation of [`TrapContext`]"]],"struct":[["TrapContext","trap context structure containing sstatus, sepc and registers"]]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["enable_timer_interrupt","init","set_kernel_trap_entry","set_user_trap_entry","trap_from_kernel","trap_handler","trap_return"],"mod":["context"],"struct":["TrapContext"]};
\ No newline at end of file
diff --git a/ch5/os/trap/struct.TrapContext.html b/ch5/os/trap/struct.TrapContext.html
index 649c8954..a30893a7 100644
--- a/ch5/os/trap/struct.TrapContext.html
+++ b/ch5/os/trap/struct.TrapContext.html
@@ -1,28 +1,33 @@
-TrapContext in os::trap - Rust Struct os::trap::TrapContext
source · [−]#[repr(C)]pub struct TrapContext {
- pub x: [usize; 32],
+TrapContext in os::trap - Rust Struct os::trap::TrapContext
source · #[repr(C)]pub struct TrapContext {
+ pub x: [usize; 32],
pub sstatus: Sstatus,
pub sepc: usize,
pub kernel_satp: usize,
pub kernel_sp: usize,
pub trap_handler: usize,
-}
Expand description
trap context structure containing sstatus, sepc and registers
-Fields
x: [usize; 32]
general regs[0..31]
-sstatus: Sstatus
CSR sstatus
-sepc: usize
CSR sepc
-kernel_satp: usize
Addr of Page Table
-kernel_sp: usize
kernel stack
-trap_handler: usize
Addr of trap_handler function
-Implementations
Auto Trait Implementations
impl RefUnwindSafe for TrapContext
impl Send for TrapContext
impl Sync for TrapContext
impl Unpin for TrapContext
impl UnwindSafe for TrapContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
trap context structure containing sstatus, sepc and registers
+Fields§
§x: [usize; 32]
general regs[0..31]
+§sstatus: Sstatus
CSR sstatus
+§sepc: usize
CSR sepc
+§kernel_satp: usize
Addr of Page Table
+§kernel_sp: usize
kernel stack
+§trap_handler: usize
Addr of trap_handler function
+Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for TrapContext
§impl Send for TrapContext
§impl Sync for TrapContext
§impl Unpin for TrapContext
§impl UnwindSafe for TrapContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
\ No newline at end of file
diff --git a/ch5/rustdoc.css b/ch5/rustdoc.css
deleted file mode 100644
index 2e22b4cf..00000000
--- a/ch5/rustdoc.css
+++ /dev/null
@@ -1 +0,0 @@
- @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:20px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}h1.fqn{margin:0;padding:0;border-bottom-color:var(--headings-border-bottom-color);}h2,h3,h4{border-bottom-color:var(--headings-border-bottom-color);}.main-heading{display:flex;flex-wrap:wrap;justify-content:space-between;padding-bottom:6px;margin-bottom:15px;}.main-heading a:hover{text-decoration:underline;}#toggle-all-docs{text-decoration:none;}h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;border-bottom-style:none;margin:0;padding:0;margin-top:0.6em;margin-bottom:0.4em;}.impl,.impl-items .method,.methods .method,.impl-items .type,.methods .type,.impl-items .associatedconstant,.methods .associatedconstant,.impl-items .associatedtype,.methods .associatedtype{flex-basis:100%;font-weight:600;position:relative;}div.impl-items>div{padding-left:0;}h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,a.source,.search-input,.search-results .result-name,.content table td:first-child>a,.item-left>a,.out-of-band,span.since,#source-sidebar,#sidebar-toggle,details.rustdoc-toggle>summary::before,div.impl-items>div:not(.docblock):not(.item-info),.content ul.crate a.crate,a.srclink,#main-content>.since,#help-button>button,details.rustdoc-toggle.top-doc>summary,details.rustdoc-toggle.top-doc>summary::before,details.rustdoc-toggle.non-exhaustive>summary,details.rustdoc-toggle.non-exhaustive>summary::before,.scraped-example-title,.more-examples-toggle summary,.more-examples-toggle .hide-more,.example-links a,#main-content>ul.docblock>li>a{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}h1,h2,h3,h4,a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,.in-band a,.search-results a,.module-item .stab,.import-item .stab,.result-name .primitive>i,.result-name .keyword>i,.content .method .where,.content .fn .where,.content .where.fmt-newline{color:var(--main-color);}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p{margin:0 0 .75em 0;}summary{outline:none;}td,th{padding:0;}table{border-collapse:collapse;}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;}button{padding:1px 6px;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.source main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}.source .width-limiter{max-width:unset;}details:not(.rustdoc-toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;}.docblock.item-decl{margin-left:0;}.item-decl pre{overflow-x:auto;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.source .content{max-width:none;overflow:visible;margin-left:0px;}nav.sub{position:relative;font-size:1rem;}.sub-container{display:flex;flex-direction:row;flex-wrap:nowrap;}.sub-logo-container{display:none;margin-right:20px;}.source .sub-logo-container{display:block;}.source .sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:var(--sidebar-background-color);}.sidebar{font-size:0.875rem;width:250px;min-width:200px;overflow-y:scroll;position:sticky;height:100vh;top:0;left:0;}.sidebar-elems,.sidebar>.location{padding-left:24px;}.sidebar .location{overflow-wrap:anywhere;}.rustdoc.source .sidebar{width:50px;min-width:0px;max-width:300px;flex-grow:0;flex-shrink:0;flex-basis:auto;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.rustdoc.source .sidebar .sidebar-logo{display:none;}.source .sidebar,#sidebar-toggle,#source-sidebar{background-color:var(--sidebar-background-color);}#sidebar-toggle>button:hover,#sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.source .sidebar>*:not(#sidebar-toggle){opacity:0;visibility:hidden;}.source-sidebar-expanded .source .sidebar{overflow-y:auto;}.source-sidebar-expanded .source .sidebar>*:not(#sidebar-toggle){opacity:1;visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{display:flex;margin-top:10px;margin-bottom:10px;justify-content:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}.location:empty{border:none;}.location a:first-of-type{font-weight:500;}.block{padding:0;}.block ul,.block li{padding:0;margin:0;list-style:none;}.block a,h2.location a{display:block;padding:0.25rem;margin-left:-0.25rem;text-overflow:ellipsis;overflow:hidden;}.sidebar h2{border-bottom:none;font-weight:500;padding:0;margin:0;margin-top:0.7rem;margin-bottom:0.7rem;}.sidebar h3{font-size:1.125rem;font-weight:500;padding:0;margin:0;}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;}.mobile-topbar{display:none;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc .example-wrap{display:inline-flex;margin-bottom:10px;}.example-wrap{position:relative;width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;padding:13px 8px;text-align:right;border-top-left-radius:5px;border-bottom-left-radius:5px;}.example-wrap>pre.rust a:hover{text-decoration:underline;}.line-numbers{text-align:right;}.rustdoc:not(.source) .example-wrap>pre:not(.line-number){width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre.line-numbers{width:auto;overflow-x:visible;}.rustdoc .example-wrap>pre{margin:0;}#search{position:relative;}.search-loading{text-align:center;}#results>table{width:100%;table-layout:fixed;}.content>.example-wrap pre.line-numbers{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock-short p{display:inline;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock>:not(pre)>code,.docblock-short>:not(pre)>code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:var(--headings-border-bottom-color);}.docblock{margin-left:24px;position:relative;}.docblock>:not(.information):not(.more-examples-toggle){max-width:100%;overflow-x:auto;}.content .out-of-band{flex-grow:0;font-size:1.125rem;font-weight:normal;float:right;}.method>.code-header,.trait-impl>.code-header{max-width:calc(100% - 41px);display:block;}.content .in-band{flex-grow:1;margin:0px;padding:0px;overflow-wrap:break-word;overflow-wrap:anywhere;}.in-band>code,.in-band>.code-header{display:inline-block;}.docblock code,.docblock-short code,pre,.rustdoc.source .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}#main-content>.since{top:inherit;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.125rem;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);overflow-x:auto;display:block;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content>.methods>.method{font-size:1rem;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.875rem;}.content .methods>div:not(.notable-traits):not(.method){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.item-info{display:block;}.content .item-info code{font-size:0.875rem;}.content .item-info{position:relative;margin-left:24px;}.sub-variant>div>.item-info{margin-top:initial;}.content .impl-items .docblock,.content .impl-items .item-info{margin-bottom:.6em;}.content .impl-items>.item-info{margin-left:40px;}.methods>.item-info,.content .impl-items>.item-info{margin-top:-8px;}.impl-items{flex-basis:100%;}#main-content>.item-info{margin-top:0;margin-left:0;}nav.sub{flex-grow:1;margin-bottom:25px;}.source nav.sub{margin-left:32px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}a{text-decoration:none;background:transparent;}.small-section-header{display:flex;justify-content:space-between;position:relative;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor,.impl:hover>.anchor,.method.trait-impl:hover>.anchor,.type.trait-impl:hover>.anchor,.associatedconstant.trait-impl:hover>.anchor,.associatedtype.trait-impl:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.anchor::before{content:'§';}.docblock a:not(.srclink):not(.test-arrow):not(.scrape-help):hover,.docblock-short a:not(.srclink):not(.test-arrow):not(.scrape-help):hover,.item-info a{text-decoration:underline;}.block a.current.crate{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;}.item-row{display:table-row;}.item-left,.item-right{display:table-cell;}.item-left{padding-right:1.25rem;}.search-container{position:relative;display:flex;height:34px;}.search-container>*{height:100%;}.search-results-title{display:inline;}#search-settings{font-size:1.5rem;font-weight:500;margin-bottom:20px;}#crate-search{min-width:115px;margin-top:5px;padding-left:0.15em;padding-right:23px;border:1px solid;border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;background-image:url("down-arrow.svg");max-width:100%;text-overflow:ellipsis;}.search-container{margin-top:4px;}.search-input{-webkit-appearance:none;-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:1px solid;border-radius:2px;padding:8px;font-size:1rem;width:100%;}.search-results{display:none;padding-bottom:2em;}.search-results.active{display:block;clear:both;}.search-results .desc>span{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results>a{display:block;width:100%;margin-left:2px;margin-right:2px;border-bottom:1px solid #aaa3;}.search-results>a>div{display:flex;flex-flow:row wrap;}.search-results .result-name,.search-results div.desc,.search-results .result-description{width:50%;}.search-results .result-name{padding-right:1em;}.search-results .result-name>span{display:inline-block;margin:0;font-weight:normal;}.popover{font-size:1rem;position:absolute;right:0;z-index:2;display:block;margin-top:7px;border-radius:3px;border:1px solid;font-size:1rem;}.popover::before{content:'';position:absolute;right:11px;border:solid;border-width:1px 1px 0 0;display:inline-block;padding:4px;transform:rotate(-45deg);top:-5px;}.popover,.popover::before{background-color:var(--main-background-color);color:var(--main-color);}#help-button .popover{max-width:600px;}#help-button .popover::before{right:48px;}#help-button dt{float:left;clear:left;display:block;margin-right:0.5rem;}#help-button span.top,#help-button span.bottom{text-align:center;display:block;font-size:1.125rem;}#help-button span.top{text-align:center;display:block;margin:10px 0;border-bottom:1px solid;padding-bottom:4px;margin-bottom:6px;}#help-button span.bottom{clear:both;border-top:1px solid;}.side-by-side{text-align:initial;}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{width:fit-content;min-height:36px;display:flex;align-items:center;white-space:pre-wrap;}.stab{padding:3px;margin-bottom:5px;font-size:0.875rem;font-weight:normal;}.stab p{display:inline;margin:0;}.stab .emoji{font-size:1.25rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.module-item .stab,.import-item .stab{border-radius:3px;display:inline-block;font-size:0.875rem;line-height:1.2;margin-bottom:0;margin-left:0.3125em;padding:2px;vertical-align:text-bottom;}.module-item.unstable,.import-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink,.methods .srclink{font-weight:normal;font-size:1rem;}.rightside{float:right;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;}.example-wrap:hover .test-arrow{visibility:visible;}a.test-arrow:hover{text-decoration:none;}.code-attribute{font-weight:300;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:1.25rem;}h3.variant{font-weight:600;font-size:1.125rem;margin-bottom:10px;border-bottom:none;}.sub-variant h4{font-size:1rem;font-weight:400;border-bottom:none;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}:target>code,:target>.code-header{opacity:1;}:target{padding-right:3px;}.information{position:absolute;left:-25px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip::after{display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;font-size:1rem;}.tooltip.ignore::after{content:"This example is not tested";}.tooltip.compile_fail::after{content:"This example deliberately fails to compile";}.tooltip.should_panic::after{content:"This example panics";}.tooltip.edition::after{content:"This code runs with edition " attr(data-edition);}.tooltip::before{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;border-width:5px;border-style:solid;display:none;}.tooltip:hover::before,.tooltip:hover::after{display:inline;}.tooltip.compile_fail,.tooltip.should_panic,.tooltip.ignore{font-weight:bold;font-size:1.25rem;}.notable-traits-tooltip{display:inline-block;cursor:pointer;}.notable-traits:hover .notable-traits-tooltiptext,.notable-traits .notable-traits-tooltiptext.force-tooltip{display:inline-block;}.notable-traits .notable-traits-tooltiptext{display:none;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;z-index:10;font-size:1rem;cursor:default;position:absolute;border:1px solid;}.notable-traits-tooltip::after{content:"\00a0\00a0\00a0";}.notable-traits .notable,.notable-traits .docblock{margin:0;}.notable-traits .notable{margin:0;margin-bottom:13px;font-size:1.1875rem;font-weight:600;display:block;}.notable-traits .docblock code.content{margin:0;padding:0;font-size:1.25rem;}pre.rust.rust-example-rendered{position:relative;}pre.rust{tab-size:4;-moz-tab-size:4;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>button{float:left;width:33.3%;text-align:center;font-size:1.125rem;cursor:pointer;border:0;border-top:2px solid;}#titles>button:first-child:last-child{margin-right:1px;width:calc(100% - 1px);}#titles>button:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>button>div.count{display:inline-block;font-size:1rem;}.notable-traits{cursor:pointer;z-index:2;margin-left:5px;}#sidebar-toggle{position:sticky;top:0;left:0;font-weight:bold;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:center;align-items:center;z-index:10;}#source-sidebar{width:100%;z-index:1;overflow:auto;}#source-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid;margin-bottom:6px;}#sidebar-toggle>button{background:none;color:inherit;cursor:pointer;text-align:center;border:none;outline:none;position:absolute;top:0;bottom:0;left:0;right:0;width:100%;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;outline:none;}#copy-path{height:34px;}#settings-menu>a,#help-button>button,#copy-path{padding:5px;width:33px;border:1px solid;border-radius:2px;cursor:pointer;}#settings-menu{padding:0;}#settings-menu>a,#help-button>button{padding:5px;height:100%;display:block;}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}.setting-line .radio-line input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-line .radio-line input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-line .radio-line input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-line .radio-line input:hover{border-color:var(--settings-input-color) !important;}input:checked+.slider{background-color:var(--settings-input-color);}#help-button>button{text-align:center;font-size:20px;padding-top:2px;}#copy-path{background:initial;margin-left:10px;padding:0;padding-left:2px;border:0;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px 8px;text-align:center;background:rgba(0,0,0,0);overflow-wrap:normal;}#theme-choices>button:not(:first-child){border-top:1px solid;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:1rem;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:1.125rem;display:block;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main-content>ul{padding-left:10px;}#main-content>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 13px;list-style-position:outside;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.rustdoc-toggle>summary.hideme{cursor:pointer;}details.rustdoc-toggle>summary{list-style:none;}details.rustdoc-toggle>summary::-webkit-details-marker,details.rustdoc-toggle>summary::marker{display:none;}details.rustdoc-toggle>summary.hideme>span{margin-left:9px;}details.rustdoc-toggle>summary::before{content:"";cursor:pointer;width:16px;height:16px;background-repeat:no-repeat;background-position:top left;display:inline-block;vertical-align:middle;opacity:.5;}details.rustdoc-toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.rustdoc-toggle>summary.hideme::after{content:"";}details.rustdoc-toggle>summary:focus::before,details.rustdoc-toggle>summary:hover::before{opacity:1;}details.rustdoc-toggle.top-doc>summary,details.rustdoc-toggle.top-doc>summary::before,details.rustdoc-toggle.non-exhaustive>summary,details.rustdoc-toggle.non-exhaustive>summary::before{font-size:1rem;}details.non-exhaustive{margin-bottom:8px;}details.rustdoc-toggle>summary.hideme::before{position:relative;}details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.rustdoc-toggle[open] >summary.hideme{position:absolute;}details.rustdoc-toggle{position:relative;}details.rustdoc-toggle[open] >summary.hideme>span{display:none;}details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle[open] >summary.hideme::before{background-image:url("toggle-minus.svg");}details.rustdoc-toggle>summary::before{background-image:url("toggle-plus.svg");}details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle[open] >summary.hideme::before{width:16px;height:16px;background-repeat:no-repeat;background-position:top left;display:inline-block;content:"";}details.rustdoc-toggle[open] >summary::after,details.rustdoc-toggle[open] >summary.hideme::after{content:"Collapse";}.docblock summary>*{display:inline-block;}@media (min-width:701px){.docblock>.information:first-child>.tooltip{margin-top:16px;}.source-sidebar-expanded .source .sidebar+main .width-limiter .sub-logo-container.rust-logo{display:none;}.source-sidebar-expanded .source .sidebar{width:300px;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{padding-top:0px;display:block;}main{padding-left:15px;padding-top:0px;}.rustdoc,.main-heading{flex-direction:column;}.content .out-of-band{text-align:left;margin-left:initial;padding:initial;}.content .out-of-band .since::before{content:"Since ";}#copy-path{display:none;}.sidebar .sidebar-logo,.sidebar .location{display:none;}.sidebar-elems{margin-top:1em;}.sidebar{position:fixed;top:45px;left:-1000px;margin-left:0;margin:0;padding:0;z-index:11;height:calc(100vh - 45px);}.source main,.rustdoc.source .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.source-sidebar-expanded .source .sidebar,.sidebar:focus-within{left:0;}.rustdoc.source>.sidebar{position:fixed;margin:0;z-index:11;width:0;}.mobile-topbar .location a{padding:0;margin:0;}.mobile-topbar .location{border:none;padding:0;margin:auto 0.5em auto auto;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;font-size:24px;}.mobile-topbar .logo-container{max-height:45px;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin-left:20px;margin-top:5px;margin-bottom:5px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.source .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;}.sidebar-elems{background-color:var(--sidebar-background-color);}.source nav:not(.sidebar).sub{margin-left:32px;}.content{margin-left:0px;}.source .content{margin-top:10px;}#search{margin-left:0;padding:0;}.anchor{display:none !important;}.notable-traits{position:absolute;left:-22px;top:24px;}#titles>button>div.count{float:left;width:100%;}#titles{height:50px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}#main-content>details.rustdoc-toggle>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}#sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;border:1px solid;border-left:0;}.source-sidebar-expanded #sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#source-sidebar{z-index:11;}#main-content>.line-numbers{margin-top:0;}.notable-traits .notable-traits-tooltiptext{left:0;top:100%;}#help-button{display:none;}.item-table{display:block;}.item-row{display:flex;flex-flow:column wrap;}.item-left,.item-right{width:100%;}.search-results>a{border-bottom:1px solid #aaa9;padding:5px 0px;}.search-results .result-name,.search-results div.desc,.search-results .result-description{width:100%;}.search-results div.desc,.search-results .result-description,.item-right{padding-left:2em;}.source-sidebar-expanded .source .sidebar{max-width:100vw;width:100vw;}details.rustdoc-toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before,#main-content>details.rustdoc-toggle:not(.top-doc)>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}}@media print{nav.sidebar,nav.sub,.content .out-of-band,a.srclink,#copy-path,details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle>summary::before,details.rustdoc-toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){#titles,#titles>button{height:73px;}#main-content>table:not(.table-display) td{word-break:break-word;width:50%;}#crate-search{border-radius:4px;}.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}.sub-container{flex-direction:column;}.sub-logo-container{align-self:center;}.source .sub-logo-container>img{height:35px;width:35px;}#sidebar-toggle{top:10px;}.source-sidebar-expanded #sidebar-toggle{top:unset;}}.method-toggle summary,.implementors-toggle summary,.impl{margin-bottom:0.75em;}.method-toggle[open]{margin-bottom:2em;}.implementors-toggle[open]{margin-bottom:2em;}#trait-implementations-list .method-toggle,#synthetic-implementations-list .method-toggle,#blanket-implementations-list .method-toggle{margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;background:transparent;border-width:1px;border-style:solid;border-radius:50px;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:240px;}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;max-height:240px;padding-bottom:0;}.scraped-example:not(.expanded) .code-wrapper pre.line-numbers{overflow-x:hidden;}.scraped-example .code-wrapper .prev{position:absolute;top:0.25em;right:2.25em;z-index:100;cursor:pointer;}.scraped-example .code-wrapper .next{position:absolute;top:0.25em;right:1.25em;z-index:100;cursor:pointer;}.scraped-example .code-wrapper .expand{position:absolute;top:0.25em;right:0.25em;z-index:100;cursor:pointer;}.scraped-example:not(.expanded) .code-wrapper:before{content:" ";width:100%;height:5px;position:absolute;z-index:100;top:0;}.scraped-example:not(.expanded) .code-wrapper:after{content:" ";width:100%;height:5px;position:absolute;z-index:100;bottom:0;}.scraped-example .code-wrapper .line-numbers{margin:0;padding:14px 0;}.scraped-example .code-wrapper .line-numbers span{padding:0 14px;}.scraped-example .code-wrapper .example-wrap{flex:1;overflow-x:auto;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .code-wrapper .example-wrap pre.rust{overflow-x:inherit;width:inherit;overflow-y:hidden;}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;margin-bottom:5px;cursor:pointer;}.more-scraped-examples{margin-left:5px;display:flex;flex-direction:row;}.more-scraped-examples-inner{width:calc(100% - 20px);}.toggle-line{align-self:stretch;margin-right:10px;margin-top:5px;padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;}.more-scraped-examples .scraped-example{margin-bottom:20px;}.more-scraped-examples .scraped-example:last-child{margin-bottom:0;}.example-links a{margin-top:20px;}.example-links ul{margin-bottom:0;}
\ No newline at end of file
diff --git a/ch5/search-index.js b/ch5/search-index.js
index 6f6e112e..f9c8276c 100644
--- a/ch5/search-index.js
+++ b/ch5/search-index.js
@@ -1,5 +1,5 @@
var searchIndex = JSON.parse('{\
-"os":{"doc":"The main module and entrypoint","t":[0,5,0,0,0,0,0,14,14,5,0,0,0,0,0,0,17,17,17,2,17,17,2,2,17,17,17,17,17,3,11,11,11,11,5,11,11,11,11,5,3,12,11,11,11,11,5,5,5,11,5,11,11,11,12,12,12,12,3,3,3,3,3,3,3,3,3,12,0,12,12,12,5,0,0,5,0,0,12,12,5,5,5,5,12,12,12,12,17,17,3,3,3,3,8,17,6,17,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,12,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,3,8,6,3,3,12,10,11,11,11,11,11,11,11,12,10,11,11,11,12,11,5,5,5,11,11,11,11,5,11,11,11,10,11,11,12,12,11,11,11,11,11,11,11,11,11,7,7,5,5,5,13,13,3,3,3,4,3,18,18,18,18,12,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,5,5,5,11,11,11,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,11,11,11,11,11,12,11,11,11,5,11,11,5,5,11,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,18,18,18,3,3,3,18,18,18,18,18,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,5,5,5,11,11,11,11,11,11,11,11,11,11,11,11,5,5,5,5,3,12,0,3,11,11,11,11,12,11,11,11,11,11,17,17,17,17,17,17,17,17,17,0,0,5,17,17,5,5,5,5,5,5,5,5,5,12,17,3,3,3,3,3,3,3,12,5,5,11,11,0,12,12,5,5,5,11,5,5,11,12,11,0,0,12,5,0,12,12,12,5,12,5,12,5,0,5,0,11,11,11,3,11,11,11,11,11,12,12,12,11,11,11,11,3,3,12,11,5,11,11,11,11,11,11,5,11,11,11,11,11,12,11,11,11,11,11,11,12,3,3,3,3,12,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,11,12,5,11,12,11,11,11,11,11,11,11,11,11,11,11,11,3,3,12,11,11,11,11,11,12,5,5,5,11,11,11,11,12,11,11,11,5,5,11,5,11,11,11,11,11,11,5,13,13,3,3,4,13,12,11,11,11,11,11,11,12,11,11,11,11,12,11,11,11,11,11,11,11,11,12,11,11,11,11,11,12,12,11,12,12,12,12,11,12,11,11,11,11,11,11,11,11,11,17,17,5,5,5,3,0,5,5,12,12,12,5,5,12,5,5,12,5,12,3,11,11,11,11,11,12,12,12,11,12,12,11,11,11,12],"n":["board","clear_bss","config","console","lang_items","loader","mm","print","println","rust_main","sbi","sync","syscall","task","timer","trap","CLOCK_FREQ","MEMORY_END","MMIO","CLOCK_FREQ","KERNEL_HEAP_SIZE","KERNEL_STACK_SIZE","MEMORY_END","MMIO","PAGE_SIZE","PAGE_SIZE_BITS","TRAMPOLINE","TRAP_CONTEXT","USER_STACK_SIZE","Stdout","borrow","borrow_mut","from","into","print","try_from","try_into","type_id","write_str","panic","APP_NAMES","__private_field","borrow","borrow_mut","deref","from","get_app_data","get_app_data_by_name","get_num_app","into","list_apps","try_from","try_into","type_id","0","0","0","0","FrameTracker","KERNEL_SPACE","MapPermission","MemorySet","PageTableEntry","PhysAddr","PhysPageNum","VirtAddr","VirtPageNum","__private_field","address","areas","bits","bits","frame_alloc","frame_allocator","heap_allocator","init","memory_set","page_table","page_table","ppn","remap_test","translated_byte_buffer","translated_refmut","translated_str","0","0","0","0","PA_WIDTH_SV39","PPN_WIDTH_SV39","PhysAddr","PhysPageNum","SimpleRange","SimpleRangeIterator","StepByOne","VA_WIDTH_SV39","VPNRange","VPN_WIDTH_SV39","VirtAddr","VirtPageNum","aligned","aligned","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","ceil","ceil","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","current","end","eq","eq","eq","eq","floor","floor","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_bytes_array","get_end","get_mut","get_mut","get_pte_array","get_start","indexes","into","into","into","into","into","into","into_iter","into_iter","l","ne","ne","ne","ne","new","new","next","page_offset","page_offset","partial_cmp","partial_cmp","partial_cmp","partial_cmp","r","step","step","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","FRAME_ALLOCATOR","FrameAllocator","FrameAllocatorImpl","FrameTracker","StackFrameAllocator","__private_field","alloc","alloc","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","current","dealloc","dealloc","deref","drop","end","fmt","frame_alloc","frame_allocator_test","frame_dealloc","from","from","from","init","init_frame_allocator","into","into","into","new","new","new","ppn","recycled","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","HEAP_ALLOCATOR","HEAP_SPACE","handle_alloc_error","heap_test","init_heap","Framed","Identical","KERNEL_SPACE","MapArea","MapPermission","MapType","MemorySet","R","U","W","X","__private_field","activate","all","areas","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","cmp","complement","contains","copy_data","data_frames","deref","difference","ebss","edata","ekernel","empty","eq","eq","erodata","etext","extend","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_another","from_bits","from_bits_truncate","from_bits_unchecked","from_elf","from_existed_user","from_iter","hash","insert","insert_framed_area","intersection","intersects","into","into","into","into","into","is_all","is_empty","map","map_one","map_perm","map_trampoline","map_type","ne","new","new_bare","new_kernel","not","page_table","partial_cmp","push","recycle_data_pages","remap_test","remove","remove_area_with_start_vpn","sbss_with_stack","sdata","set","srodata","stext","strampoline","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","union","unmap","unmap_one","vpn_range","A","D","G","PTEFlags","PageTable","PageTableEntry","R","U","V","W","X","all","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","cmp","complement","contains","difference","empty","empty","eq","executable","extend","find_pte","find_pte_create","flags","fmt","fmt","fmt","fmt","fmt","frames","from","from","from","from_bits","from_bits_truncate","from_bits_unchecked","from_iter","from_token","hash","insert","intersection","intersects","into","into","into","is_all","is_empty","is_valid","map","ne","new","new","not","partial_cmp","ppn","readable","remove","root_ppn","set","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","translate_va","translated_byte_buffer","translated_refmut","translated_str","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","union","unmap","writable","console_getchar","console_putchar","set_timer","shutdown","UPSafeCell","inner","up","UPSafeCell","borrow","borrow_mut","exclusive_access","from","inner","into","new","try_from","try_into","type_id","SYSCALL_EXEC","SYSCALL_EXIT","SYSCALL_FORK","SYSCALL_GETPID","SYSCALL_GET_TIME","SYSCALL_READ","SYSCALL_WAITPID","SYSCALL_WRITE","SYSCALL_YIELD","fs","process","syscall","FD_STDIN","FD_STDOUT","sys_read","sys_write","sys_exec","sys_exit","sys_fork","sys_get_time","sys_getpid","sys_waitpid","sys_yield","0","IDLE_PID","INITPROC","KernelStack","PidAllocator","PidHandle","Processor","TaskContext","TaskManager","__private_field","add_initproc","add_task","borrow","borrow_mut","context","current","current","current_task","current_trap_cx","current_user_token","deref","exit_current_and_run_next","fetch_task","from","idle_task_cx","into","manager","pid","pid","pid_alloc","processor","ra","ready_queue","recycled","run_tasks","s","schedule","sp","suspend_current_and_run_next","switch","take_current_task","task","try_from","try_into","type_id","TaskContext","borrow","borrow_mut","from","goto_trap_return","into","ra","s","sp","try_from","try_into","type_id","zero_init","TASK_MANAGER","TaskManager","__private_field","add","add_task","borrow","borrow","borrow_mut","borrow_mut","deref","fetch","fetch_task","from","from","into","into","new","ready_queue","try_from","try_from","try_into","try_into","type_id","type_id","0","KernelStack","PID_ALLOCATOR","PidAllocator","PidHandle","__private_field","alloc","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","current","dealloc","deref","drop","drop","from","from","from","from","get_top","into","into","into","into","kernel_stack_position","new","new","pid","pid_alloc","push_on_top","recycled","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","PROCESSOR","Processor","__private_field","borrow","borrow","borrow_mut","borrow_mut","current","current","current_task","current_trap_cx","current_user_token","deref","from","from","get_idle_task_cx_ptr","idle_task_cx","into","into","new","run_tasks","schedule","take_current","take_current_task","try_from","try_from","try_into","try_into","type_id","type_id","__switch","Ready","Running","TaskControlBlock","TaskControlBlockInner","TaskStatus","Zombie","base_size","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","children","clone","clone_into","eq","exec","exit_code","fork","from","from","from","get_status","get_trap_cx","get_user_token","getpid","inner","inner_exclusive_access","into","into","into","is_zombie","kernel_stack","memory_set","new","parent","pid","task_cx","task_status","to_owned","trap_cx_ppn","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","MSEC_PER_SEC","TICKS_PER_SEC","get_time","get_time_ms","set_next_trigger","TrapContext","context","enable_timer_interrupt","init","kernel_satp","kernel_sp","sepc","set_kernel_trap_entry","set_user_trap_entry","sstatus","trap_from_kernel","trap_handler","trap_handler","trap_return","x","TrapContext","app_init_context","borrow","borrow_mut","from","into","kernel_satp","kernel_sp","sepc","set_sp","sstatus","trap_handler","try_from","try_into","type_id","x"],"q":["os","","","","","","","","","","","","","","","","os::board","","","os::config","","","","","","","","","","os::console","","","","","","","","","","os::lang_items","os::loader","","","","","","","","","","","","","","os::mm","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::mm::address","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::mm::frame_allocator","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::mm::heap_allocator","","","","","os::mm::memory_set","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::mm::page_table","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::sbi","","","","os::sync","","","os::sync::up","","","","","","","","","","","os::syscall","","","","","","","","","","","","os::syscall::fs","","","","os::syscall::process","","","","","","","os::task","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::task::context","","","","","","","","","","","","","os::task::manager","","","","","","","","","","","","","","","","","","","","","","","","os::task::pid","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::task::processor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::task::switch","os::task::task","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","os::timer","","","","","os::trap","","","","","","","","","","","","","","","os::trap::context","","","","","","","","","","","","","","",""],"d":["Constants used in rCore for qemu","clear BSS segment","Constants used in rCore","SBI console driver, for text output","The panic handler","Loading user applications into memory","Memory management implementation","print string macro","println string macro","the rust entry-point of os","SBI call wrappers","Synchronization and interior mutability primitives","Implementation of syscalls","Task management implementation","RISC-V timer-related functionality","Trap handling functionality","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","All of app’s name","","","","","Returns the argument unchanged.","get applications data","get app data from name","get app number","Calls U::from(self)
.","list all apps","","","","","","","","manage a frame which has the same lifecycle as the tracker","a memory set instance through lazy_static! managing kernel …","map permission corresponding to that in pte: R W X U
","memory set structure, controls virtual-memory space","page table entry structure","physical address","physical page number","virtual address","virtual page number","","Implementation of physical and virtual address and page …","","","PTE","allocate a frame","Implementation of FrameAllocator
which controls all the …","The global allocator","initiate heap allocator, frame allocator and kernel space","Implementation of MapArea
and MemorySet
.","Implementation of PageTableEntry
and PageTable
.","","","Check PageTable running correctly","translate a pointer to a mutable u8 Vec through page table","translate a generic through page table and return a …","translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","physical address","","physical address","physical page number","a simple range structure for type T","iterator for the simple range structure","","","a simple range structure for virtual page number","","virtual address","virtual page number","Check page aligned","Check page aligned","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","","","","","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","Get mutable reference to PhysAddr
value","","Get PageTableEntry
on PhysPageNum
","","Return VPN 3 level index","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","Get page offset","Get page offset","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","frame allocator instance through lazy_static!","","","manage a frame which has the same lifecycle as the tracker","an implementation for frame allocator","","","","","","","","","","","","","","","","","allocate a frame","a simple test for frame allocator","deallocate a frame","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","initiate the frame allocator using ekernel
and MEMORY_END
","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","Create an empty FrameTracker
","","","","","","","","","","","","","heap allocator instance","heap space ([u8; KERNEL_HEAP_SIZE])","panic when heap allocation error occurs","","initiate heap allocator","","","a memory set instance through lazy_static! managing kernel …","map area structure, controls a contiguous piece of virtual …","map permission corresponding to that in pte: R W X U
","map type for memory set: identical or framed","memory set structure, controls virtual-memory space","Readable","Accessible in U mode","Writable","Excutable","","Refresh TLB with sfence.vma
","Returns the set containing all flags.","","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","data: start-aligned but maybe with shorter length assume …","","","Returns the difference between the flags in self
and other
.","","","","Returns an empty set of flags.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","Include sections in elf and trampoline and TrapContext and …","Clone a same MemorySet
","","","Inserts the specified flags in-place.","Assume that no conflicts.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","","","","Mention that trampoline is not collected by areas.","","","","Create an empty MemorySet
","Without kernel stacks.","Returns the complement of this set of flags.","","","","Remove all MapArea
","Check PageTable running correctly","Removes the specified flags in-place.","Remove MapArea
that starts with start_vpn
","","","Inserts or removes the specified flags depending on the …","","","","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get pagetable root_ppn
","Translate throuth pagetable","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","","","","","","page table entry structure","","","","","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","PTE","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","Return an empty PTE","","Check PTE executable","","","","Return 10bit flag","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","Temporarily used to get arguments from user space.","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Check PTE valid","","","","Create a PTE from ppn","Returns the complement of this set of flags.","","Return 44bit ppn","Check PTE readable","Removes the specified flags in-place.","","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","","","","translate a pointer to a mutable u8 Vec through page table","translate a generic through page table and return a …","translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","","","","","","Returns the union of between the flags in self
and other
.","","Check PTE writable","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","use sbi call to set timer","use sbi call to shutdown the kernel","Wrap a static data structure inside it so that we are able …","inner data","Uniprocessor interior mutability primitives","Wrap a static data structure inside it so that we are able …","","","Exclusive access inner data in UPSafeCell. Panic if the …","Returns the argument unchanged.","inner data","Calls U::from(self)
.","User is responsible to guarantee that inner struct is only …","","","","","","","","","","","","","File and filesystem-related syscalls","","handle syscall exception with syscall_id
and other …","","","","","","","","","","If there is not a child process whose pid is same as …","","","pid of usertests app in make run TEST=1","Globle process that init user shell","Kernelstack for app","Pid Allocator struct","Bind pid lifetime to PidHandle
","Processor management structure","task context structure containing some registers","A array of TaskControlBlock
that is thread-safe","","Add init process to the manager","Interface offered to add task","","","Implementation of TaskContext
","","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Exit the current ‘Running’ task and run the next task …","Interface offered to pop the first task","Returns the argument unchanged.","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Implementation of TaskManager
","Implementation of PidAllocator
","","Allocate a pid from PID_ALLOCATOR","Implementation of Processor
and Intersection of control …","return address ( e.g. __restore ) of __switch ASM function","","","The main part of process execution and scheduling Loop …","s0-11 register, callee saved","Return to idle control flow for new scheduling","kernel stack pointer of app","Suspend the current ‘Running’ task and run the next …","Wrap switch.S
as a function","Take the current task,leaving a None in its place","Implementation of TaskControlBlock
","","","","task context structure containing some registers","","","Returns the argument unchanged.","set Task Context{__restore ASM funciton: trap_return, sp: …","Calls U::from(self)
.","return address ( e.g. __restore ) of __switch ASM function","s0-11 register, callee saved","kernel stack pointer of app","","","","init task context","","A array of TaskControlBlock
that is thread-safe","","Add a task to TaskManager
","Interface offered to add task","","","","","","Remove the first task and return it,or None
if TaskManager
…","Interface offered to pop the first task","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Creat an empty TaskManager","","","","","","","","","Kernelstack for app","","Pid Allocator struct","Bind pid lifetime to PidHandle
","","Allocate a pid","","","","","","","","","","Recycle a pid","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get the value on the top of kernelstack","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Return (bottom, top) of a kernel stack in kernel space.","Create an empty PidAllocator
","Create a kernelstack from pid","","Allocate a pid from PID_ALLOCATOR","Push a value on top of kernelstack","","","","","","","","","","","","","","","Processor management structure","","","","","","Get current task in cloning semanteme","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Returns the argument unchanged.","Returns the argument unchanged.","Get mutable reference to idle_task_cx
","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Calls U::from(self)
.","Create an empty Processor","The main part of process execution and scheduling Loop …","Return to idle control flow for new scheduling","Get current task in moving semanteme","Take the current task,leaving a None in its place","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","","get current time","get current time in microseconds","set the next timer interrupt","trap context structure containing sstatus, sepc and …","Implementation of TrapContext
","enable timer interrupt in sie CSR","initialize CSR stvec
as the entry of __alltraps
","Addr of Page Table","kernel stack","CSR sepc","","","CSR sstatus ","Unimplement: traps/interrupts/exceptions from kernel mode …","handle an interrupt, exception, or system call from user …","Addr of trap_handler function","set the new addr of __restore asm function in TRAMPOLINE …","general regs[0..31]","trap context structure containing sstatus, sepc and …","init app context","","","Returns the argument unchanged.","Calls U::from(self)
.","Addr of Page Table","kernel stack","CSR sepc","set stack pointer to x_2 reg (sp)","CSR sstatus ","Addr of trap_handler function","","","","general regs[0..31]"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,5,5,5,5,0,0,9,9,9,9,9,0,0,0,9,0,9,9,9,16,18,19,20,0,0,0,0,0,0,0,0,0,35,0,30,31,38,0,0,0,0,0,0,30,13,0,0,0,0,16,18,19,20,0,0,0,0,0,0,0,0,0,0,0,0,16,18,25,16,18,19,20,22,25,16,18,19,20,22,16,18,16,18,19,20,22,16,18,19,20,22,16,18,19,20,25,25,16,18,19,20,16,18,16,18,19,20,25,16,16,16,18,18,18,19,19,19,20,20,20,22,19,22,16,19,19,22,20,25,16,18,19,20,22,25,22,22,16,18,19,20,25,22,25,16,18,16,18,19,20,22,57,20,16,18,19,20,22,25,16,18,19,20,22,25,16,18,19,20,22,25,16,18,19,20,22,0,0,0,0,0,27,58,26,13,26,27,13,26,27,26,58,26,27,13,26,13,0,0,0,13,26,27,26,0,13,26,27,58,13,26,13,26,13,26,27,13,26,27,13,26,27,0,0,0,0,0,32,32,0,0,0,0,0,31,31,31,31,35,30,31,30,31,31,31,31,31,31,31,31,30,33,35,32,31,30,33,35,32,31,32,31,32,31,31,31,31,33,33,35,31,0,0,0,31,32,31,0,0,31,32,31,31,31,31,31,30,33,35,32,31,33,31,31,31,30,30,31,31,31,30,31,31,30,33,35,32,31,31,31,33,33,33,30,33,31,33,30,30,31,30,31,30,30,0,31,30,0,0,31,0,0,0,31,31,31,32,31,31,30,30,30,33,35,32,31,30,33,35,32,31,30,33,35,32,31,31,33,33,33,39,39,39,0,0,0,39,39,39,39,39,39,39,39,39,39,39,39,38,39,39,34,39,38,34,39,38,39,38,39,38,39,39,39,39,39,38,39,38,39,34,34,38,39,39,39,39,39,34,34,39,38,39,39,39,39,34,39,39,39,39,34,39,38,39,39,38,34,39,34,38,39,39,38,38,39,34,39,39,39,39,39,38,39,34,34,34,0,0,0,34,39,38,34,39,38,34,39,38,39,34,38,0,0,0,0,0,28,0,0,28,28,28,28,28,28,28,28,28,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,0,0,0,0,0,0,0,0,45,0,0,45,45,0,50,53,0,0,0,45,0,0,45,53,45,0,0,52,0,0,47,48,50,0,47,0,47,0,0,0,0,45,45,45,0,47,47,47,47,47,47,47,47,47,47,47,47,0,0,49,48,0,48,49,48,49,49,48,0,48,49,48,49,48,48,48,49,48,49,48,49,46,0,0,0,0,51,50,50,46,52,51,50,46,52,51,50,50,51,46,52,50,46,52,51,52,50,46,52,51,0,50,52,52,0,52,50,50,46,52,51,50,46,52,51,50,46,52,51,0,0,54,53,54,53,54,53,53,0,0,0,54,53,54,53,53,53,54,53,0,0,53,0,53,54,53,54,53,54,0,55,55,0,0,0,55,56,43,56,55,43,56,55,56,55,55,55,43,56,43,43,56,55,56,56,56,43,43,43,43,56,55,56,43,56,43,56,43,56,56,55,56,43,56,55,43,56,55,43,56,55,0,0,0,0,0,0,0,0,0,44,44,44,0,0,44,0,0,44,0,44,0,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44],"f":[0,[[]],0,0,0,0,0,0,0,[[],1],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[2],[[],3],[[],3],[[],4],[[5,6],7],[8,1],0,0,[[]],[[]],[9,10],[[]],[11],[6,12],[[],11],[[]],[[]],[[],3],[[],3],[[],4],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],[[12,[13]]]],0,0,[[]],0,0,0,0,[[]],[[11,14,11],10],[11],[[11,14],15],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[16,17],[18,17],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[16,19],[18,20],[16,16],[18,18],[19,19],[20,20],[[[22,[21]]],[[22,[21]]]],[[]],[[]],[[]],[[]],[[]],[[16,16],23],[[18,18],23],[[19,19],23],[[20,20],23],0,0,[[16,16],17],[[18,18],17],[[19,19],17],[[20,20],17],[16,19],[18,20],[[16,24],7],[[18,24],7],[[19,24],7],[[20,24],7],[[]],[11,16],[19,16],[[]],[[]],[20,18],[11,18],[[]],[11,19],[16,19],[[]],[18,20],[11,20],[[]],[19],[22],[16],[19],[19],[22],[20],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[22],0,[[16,16],17],[[18,18],17],[[19,19],17],[[20,20],17],[[],25],[[],22],[25,12],[16,11],[18,11],[[16,16],[[12,[23]]]],[[18,18],[[12,[23]]]],[[19,19],[[12,[23]]]],[[20,20],[[12,[23]]]],0,[[]],[20],[[]],[[]],[[]],[[]],[[]],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],[[],4],[[],4],[[],4],0,0,0,0,0,0,[[],[[12,[19]]]],[26,[[12,[19]]]],[[]],[[]],[[]],[[]],[[]],[[]],0,[19],[[26,19]],[27,28],[13],0,[[13,24],7],[[],[[12,[13]]]],[[]],[19],[[]],[[]],[[]],[[26,19,19]],[[]],[[]],[[]],[[]],[[]],[19,13],[[],26],0,0,[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],0,0,[29,1],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,[30],[[],31],0,[[31,31],31],[[31,31]],[[31,31],31],[[31,31]],[31,14],0,[[31,31],31],[[31,31]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[32,32],[31,31],[[]],[[]],[[31,31],23],[31,31],[[31,31],17],[[33,34]],0,[35,36],[[31,31],31],0,0,0,[[],31],[[32,32],17],[[31,31],17],0,0,[[31,37]],[[32,24],7],[[31,24],7],[[31,24],7],[[31,24],7],[[31,24],7],[[31,24],7],[[]],[[]],[[]],[[]],[[]],[33,33],[14,[[12,[31]]]],[14,31],[14,31],[[]],[30,30],[37,31],[31],[[31,31]],[[30,18,18,31]],[[31,31],31],[[31,31],17],[[]],[[]],[[]],[[]],[[]],[31,17],[31,17],[[33,34]],[[33,34,20]],0,[30],0,[[31,31],17],[[18,18,32,31],33],[[],30],[[],30],[31,31],0,[[31,31],[[12,[23]]]],[[30,33,12]],[30],[[]],[[31,31]],[[30,20]],0,0,[[31,31,17]],0,0,0,[[31,31],31],[[31,31]],[[31,31],31],[[]],[[]],[[31,31]],[30,11],[[30,20],[[12,[38]]]],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],[[],4],[[],4],[[31,31],31],[[33,34]],[[33,34,20]],0,0,0,0,0,0,0,0,0,0,0,0,[[],39],[[39,39],39],[[39,39]],[[39,39],39],[[39,39]],[39,14],0,0,[[39,39],39],[[39,39]],[[]],[[]],[[]],[[]],[[]],[[]],[39,39],[38,38],[[]],[[]],[[39,39],23],[39,39],[[39,39],17],[[39,39],39],[[],39],[[],38],[[39,39],17],[38,17],[[39,37]],[[34,20],[[12,[38]]]],[[34,20],[[12,[38]]]],[38,39],[[39,24],7],[[39,24],7],[[39,24],7],[[39,24],7],[[39,24],7],0,[[]],[[]],[[]],[14,[[12,[39]]]],[14,39],[14,39],[37,39],[11,34],[39],[[39,39]],[[39,39],39],[[39,39],17],[[]],[[]],[[]],[39,17],[39,17],[38,17],[[34,20,19,39]],[[39,39],17],[[],34],[[19,39],38],[39,39],[[39,39],[[12,[23]]]],[38,19],[38,17],[[39,39]],0,[[39,39,17]],[[39,39],39],[[39,39]],[[39,39],39],[[]],[[]],[[39,39]],[34,11],[[34,20],[[12,[38]]]],[[34,18],[[12,[16]]]],[[11,14,11],10],[11],[[11,14],15],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],[[39,39],39],[[34,20]],[38,17],[[],11],[11],[11],[17,1],0,0,0,0,[[]],[[]],[28,40],[[]],0,[[]],[[],28],[[],3],[[],3],[[],4],0,0,0,0,0,0,0,0,0,0,0,[11,41],0,0,[[11,14,11],41],[[11,14,11],41],[14,41],[42,1],[[],41],[[],41],[[],41],[[41,42],41],[[],41],0,0,0,0,0,0,0,0,0,0,[[]],[[[36,[43]]]],[[]],[[]],0,0,0,[[],[[12,[[36,[43]]]]]],[[],44],[[],11],[45,36],[42],[[],[[12,[[36,[43]]]]]],[[]],0,[[]],0,0,0,[[],46],0,0,0,0,[[]],0,[47],0,[[]],0,[[],[[12,[[36,[43]]]]]],0,[[],3],[[],3],[[],4],0,[[]],[[]],[[]],[11,47],[[]],0,0,0,[[],3],[[],3],[[],4],[[],47],0,0,0,[[48,[36,[43]]]],[[[36,[43]]]],[[]],[[]],[[]],[[]],[49,28],[48,[[12,[[36,[43]]]]]],[[],[[12,[[36,[43]]]]]],[[]],[[]],[[]],[[]],[[],48],0,[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],0,0,0,0,0,0,[50,46],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[50,11]],[51,28],[46],[52],[[]],[[]],[[]],[[]],[52,11],[[]],[[]],[[]],[[]],[11],[[],50],[46,52],0,[[],46],[52],0,[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],[[],4],0,0,0,[[]],[[]],[[]],[[]],[53,[[12,[[36,[43]]]]]],0,[[],[[12,[[36,[43]]]]]],[[],44],[[],11],[54,28],[[]],[[]],[53,47],0,[[]],[[]],[[],53],[[]],[47],[53,[[12,[[36,[43]]]]]],[[],[[12,[[36,[43]]]]]],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],0,[55,55],[[]],[[55,55],17],[43],0,[36,[[36,[43]]]],[[]],[[]],[[]],[56,55],[56,44],[56,11],[43,11],0,[43,[[40,[56]]]],[[]],[[]],[[]],[56,17],0,0,[[],43],0,0,0,0,[[]],0,[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],4],[[],4],[[],4],0,0,[[],11],[[],11],[[]],0,0,[[]],[[]],0,0,0,[[]],[[]],0,[[],1],[[],1],0,[[],1],0,0,[[11,11,11,11,11],44],[[]],[[]],[[]],[[]],0,0,0,[[44,11]],0,0,[[],3],[[],3],[[],4],0],"p":[[15,"never"],[3,"Arguments"],[4,"Result"],[3,"TypeId"],[3,"Stdout"],[15,"str"],[6,"Result"],[3,"PanicInfo"],[3,"APP_NAMES"],[3,"Vec"],[15,"usize"],[4,"Option"],[3,"FrameTracker"],[15,"u8"],[3,"String"],[3,"PhysAddr"],[15,"bool"],[3,"VirtAddr"],[3,"PhysPageNum"],[3,"VirtPageNum"],[8,"Clone"],[3,"SimpleRange"],[4,"Ordering"],[3,"Formatter"],[3,"SimpleRangeIterator"],[3,"StackFrameAllocator"],[3,"FRAME_ALLOCATOR"],[3,"UPSafeCell"],[3,"Layout"],[3,"MemorySet"],[3,"MapPermission"],[4,"MapType"],[3,"MapArea"],[3,"PageTable"],[3,"KERNEL_SPACE"],[3,"Arc"],[8,"IntoIterator"],[3,"PageTableEntry"],[3,"PTEFlags"],[3,"RefMut"],[15,"isize"],[15,"i32"],[3,"TaskControlBlock"],[3,"TrapContext"],[3,"INITPROC"],[3,"PidHandle"],[3,"TaskContext"],[3,"TaskManager"],[3,"TASK_MANAGER"],[3,"PidAllocator"],[3,"PID_ALLOCATOR"],[3,"KernelStack"],[3,"Processor"],[3,"PROCESSOR"],[4,"TaskStatus"],[3,"TaskControlBlockInner"],[8,"StepByOne"],[8,"FrameAllocator"]]}\
+"os":{"doc":"The main module and entrypoint","t":"AFAAAAAOOFAAAAAARRRCRRCCRRRRRDLLLLFLLLLFDMLLLLFFFLFLLLDCCDDDDDDDDMAMMMFAAFAAMMFFFFRRDDDDIRGRDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLMMKLLLLLLLLLLLLLLLLLLLLLLLLDIGDDMKLLLLLLLMMKLLLMMLFFFLLLLFLLLKLLMMMLLLLLLLLLHHFFFNNDDDEDSSSSMLLMLLLLLMLLLLLLLLLLLLLLLLLLLLMLLFFFLLLFFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMLLLLMLLLFLLFFLFFFLLLLLLLLLLLLLLLLLLLLLLLLLLMSSSDDDSSSSSLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLFFFLLLLLLLLLLLLFFFFDMADLLLLMLLLLLRRRRRRRRRAAFRRFFFFFFFFFRDDDDDDDMFFLLAMMFFFLFFLMLAAMFAMMMFMFMFAFALLLDLLLLLMMMLLLLDDMLFLLLLLLFLLLLLMLLLLLLDDDDMLLLLLLLLLMLLLLLLLLLLLLLFLLMFLMLLLLLLLLLLLLDDMLLLLLMFFFLLLLMLLLFFLFLLLLLLFNNDDENMLLLLLLMLLLLMLLLLLLLLMLLLLLMMLMMMMLMLLLLLLLLLRRFFFDAFFMMMFFMFFMFMDLLLLLMMMLMMLLLM","n":["board","clear_bss","config","console","lang_items","loader","mm","print","println","rust_main","sbi","sync","syscall","task","timer","trap","CLOCK_FREQ","MEMORY_END","MMIO","CLOCK_FREQ","KERNEL_HEAP_SIZE","KERNEL_STACK_SIZE","MEMORY_END","MMIO","PAGE_SIZE","PAGE_SIZE_BITS","TRAMPOLINE","TRAP_CONTEXT","USER_STACK_SIZE","Stdout","borrow","borrow_mut","from","into","print","try_from","try_into","type_id","write_str","panic","APP_NAMES","__private_field","borrow","borrow_mut","deref","from","get_app_data","get_app_data_by_name","get_num_app","into","list_apps","try_from","try_into","type_id","FrameTracker","KERNEL_SPACE","KERNEL_SPACE","KERNEL_SPACE","MapPermission","MemorySet","PageTableEntry","PhysAddr","PhysPageNum","VirtAddr","VirtPageNum","__private_field","address","areas","bits","bits","frame_alloc","frame_allocator","heap_allocator","init","memory_set","page_table","page_table","ppn","remap_test","translated_byte_buffer","translated_refmut","translated_str","PA_WIDTH_SV39","PPN_WIDTH_SV39","PhysAddr","PhysPageNum","SimpleRange","SimpleRangeIterator","StepByOne","VA_WIDTH_SV39","VPNRange","VPN_WIDTH_SV39","VirtAddr","VirtPageNum","aligned","aligned","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","ceil","ceil","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","current","end","eq","eq","eq","eq","floor","floor","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_bytes_array","get_end","get_mut","get_mut","get_pte_array","get_start","indexes","into","into","into","into","into","into","into_iter","into_iter","l","l","new","new","next","page_offset","page_offset","partial_cmp","partial_cmp","partial_cmp","partial_cmp","r","r","step","step","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","FRAME_ALLOCATOR","FrameAllocator","FrameAllocatorImpl","FrameTracker","StackFrameAllocator","__private_field","alloc","alloc","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","current","current","dealloc","dealloc","deref","drop","end","end","fmt","frame_alloc","frame_allocator_test","frame_dealloc","from","from","from","init","init_frame_allocator","into","into","into","new","new","new","ppn","recycled","recycled","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","HEAP_ALLOCATOR","HEAP_SPACE","handle_alloc_error","heap_test","init_heap","Framed","Identical","KERNEL_SPACE","MapArea","MapPermission","MapType","MemorySet","R","U","W","X","__private_field","activate","all","areas","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","cmp","complement","contains","copy_data","data_frames","deref","difference","ebss","edata","ekernel","empty","eq","eq","erodata","etext","extend","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_another","from_bits","from_bits_truncate","from_bits_unchecked","from_elf","from_existed_user","from_iter","hash","insert","insert_framed_area","intersection","intersects","into","into","into","into","into","is_all","is_empty","map","map_one","map_perm","map_trampoline","map_type","new","new_bare","new_kernel","not","page_table","partial_cmp","push","recycle_data_pages","remap_test","remove","remove_area_with_start_vpn","sbss_with_stack","sdata","set","srodata","stext","strampoline","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","union","unmap","unmap_one","vpn_range","A","D","G","PTEFlags","PageTable","PageTableEntry","R","U","V","W","X","all","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","cmp","complement","contains","difference","empty","empty","eq","executable","extend","find_pte","find_pte_create","flags","fmt","fmt","fmt","fmt","fmt","frames","from","from","from","from_bits","from_bits_truncate","from_bits_unchecked","from_iter","from_token","hash","insert","intersection","intersects","into","into","into","is_all","is_empty","is_valid","map","new","new","not","partial_cmp","ppn","readable","remove","root_ppn","set","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","translate_va","translated_byte_buffer","translated_refmut","translated_str","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","union","unmap","writable","console_getchar","console_putchar","set_timer","shutdown","UPSafeCell","inner","up","UPSafeCell","borrow","borrow_mut","exclusive_access","from","inner","into","new","try_from","try_into","type_id","SYSCALL_EXEC","SYSCALL_EXIT","SYSCALL_FORK","SYSCALL_GETPID","SYSCALL_GET_TIME","SYSCALL_READ","SYSCALL_WAITPID","SYSCALL_WRITE","SYSCALL_YIELD","fs","process","syscall","FD_STDIN","FD_STDOUT","sys_read","sys_write","sys_exec","sys_exit","sys_fork","sys_get_time","sys_getpid","sys_waitpid","sys_yield","IDLE_PID","INITPROC","KernelStack","PidAllocator","PidHandle","Processor","TaskContext","TaskManager","__private_field","add_initproc","add_task","borrow","borrow_mut","context","current","current","current_task","current_trap_cx","current_user_token","deref","exit_current_and_run_next","fetch_task","from","idle_task_cx","into","manager","pid","pid","pid_alloc","processor","ra","ready_queue","recycled","run_tasks","s","schedule","sp","suspend_current_and_run_next","switch","take_current_task","task","try_from","try_into","type_id","TaskContext","borrow","borrow_mut","from","goto_trap_return","into","ra","s","sp","try_from","try_into","type_id","zero_init","TASK_MANAGER","TaskManager","__private_field","add","add_task","borrow","borrow","borrow_mut","borrow_mut","deref","fetch","fetch_task","from","from","into","into","new","ready_queue","try_from","try_from","try_into","try_into","type_id","type_id","KernelStack","PID_ALLOCATOR","PidAllocator","PidHandle","__private_field","alloc","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","current","dealloc","deref","drop","drop","from","from","from","from","get_top","into","into","into","into","kernel_stack_position","new","new","pid","pid_alloc","push_on_top","recycled","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","PROCESSOR","Processor","__private_field","borrow","borrow","borrow_mut","borrow_mut","current","current","current_task","current_trap_cx","current_user_token","deref","from","from","get_idle_task_cx_ptr","idle_task_cx","into","into","new","run_tasks","schedule","take_current","take_current_task","try_from","try_from","try_into","try_into","type_id","type_id","__switch","Ready","Running","TaskControlBlock","TaskControlBlockInner","TaskStatus","Zombie","base_size","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","children","clone","clone_into","eq","exec","exit_code","fork","from","from","from","get_status","get_trap_cx","get_user_token","getpid","inner","inner_exclusive_access","into","into","into","is_zombie","kernel_stack","memory_set","new","parent","pid","task_cx","task_status","to_owned","trap_cx_ppn","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","MSEC_PER_SEC","TICKS_PER_SEC","get_time","get_time_ms","set_next_trigger","TrapContext","context","enable_timer_interrupt","init","kernel_satp","kernel_sp","sepc","set_kernel_trap_entry","set_user_trap_entry","sstatus","trap_from_kernel","trap_handler","trap_handler","trap_return","x","TrapContext","app_init_context","borrow","borrow_mut","from","into","kernel_satp","kernel_sp","sepc","set_sp","sstatus","trap_handler","try_from","try_into","type_id","x"],"q":[[0,"os"],[16,"os::board"],[19,"os::config"],[29,"os::console"],[39,"os::lang_items"],[40,"os::loader"],[54,"os::mm"],[82,"os::mm::address"],[203,"os::mm::frame_allocator"],[252,"os::mm::heap_allocator"],[257,"os::mm::memory_set"],[389,"os::mm::page_table"],[490,"os::sbi"],[494,"os::sync"],[497,"os::sync::up"],[508,"os::syscall"],[520,"os::syscall::fs"],[524,"os::syscall::process"],[531,"os::task"],[575,"os::task::context"],[588,"os::task::manager"],[612,"os::task::pid"],[659,"os::task::processor"],[689,"os::task::switch"],[690,"os::task::task"],[741,"os::timer"],[746,"os::trap"],[761,"os::trap::context"],[777,"core::fmt"],[778,"core::result"],[779,"core::any"],[780,"core::fmt"],[781,"alloc::vec"],[782,"core::option"],[783,"alloc::string"],[784,"core::marker"],[785,"core::cmp"],[786,"core::cmp"],[787,"core::cmp"],[788,"alloc::sync"],[789,"core::iter::traits::collect"],[790,"core::hash"],[791,"core::cell"],[792,"core::marker"]],"d":["Constants used in rCore for qemu","clear BSS segment","Constants used in rCore","SBI console driver, for text output","The panic handler","Loading user applications into memory","Memory management implementation","print string macro","println string macro","the rust entry-point of os","SBI call wrappers","Synchronization and interior mutability primitives","Implementation of syscalls","Task management implementation","RISC-V timer-related functionality","Trap handling functionality","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","All of app’s name","","","","","Returns the argument unchanged.","get applications data","get app data from name","get app number","Calls U::from(self)
.","list all apps","","","","manage a frame which has the same lifecycle as the tracker","","","a memory set instance through lazy_static! managing kernel …","map permission corresponding to that in pte: R W X U
","memory set structure, controls virtual-memory space","page table entry structure","physical address","physical page number","virtual address","virtual page number","","Implementation of physical and virtual address and page …","","","PTE","allocate a frame","Implementation of FrameAllocator
which controls all the …","The global allocator","initiate heap allocator, frame allocator and kernel space","Implementation of MapArea
and MemorySet
.","Implementation of PageTableEntry
and PageTable
.","","","Check PageTable running correctly","translate a pointer to a mutable u8 Vec through page table","translate a generic through page table and return a …","translate a pointer to a mutable u8 Vec end with \\\\0
…","physical address","","physical address","physical page number","a simple range structure for type T","iterator for the simple range structure","","","a simple range structure for virtual page number","","virtual address","virtual page number","Check page aligned","Check page aligned","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","","","","","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","Get mutable reference to PhysAddr
value","","Get PageTableEntry
on PhysPageNum
","","Return VPN 3 level index","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","Get page offset","Get page offset","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","frame allocator instance through lazy_static!","","","manage a frame which has the same lifecycle as the tracker","an implementation for frame allocator","","","","","","","","","","","","","","","","","","","allocate a frame","a simple test for frame allocator","deallocate a frame","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","initiate the frame allocator using ekernel
and MEMORY_END
","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","Create an empty FrameTracker
","","","","","","","","","","","","","","heap allocator instance","heap space ([u8; KERNEL_HEAP_SIZE])","panic when heap allocation error occurs","","initiate heap allocator","","","a memory set instance through lazy_static! managing kernel …","map area structure, controls a contiguous piece of virtual …","map permission corresponding to that in pte: R W X U
","map type for memory set: identical or framed","memory set structure, controls virtual-memory space","Readable","Accessible in U mode","Writable","Excutable","","Refresh TLB with sfence.vma
","Returns the set containing all flags.","","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","data: start-aligned but maybe with shorter length assume …","","","Returns the difference between the flags in self
and other
.","","","","Returns an empty set of flags.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","Include sections in elf and trampoline and TrapContext and …","Clone a same MemorySet
","","","Inserts the specified flags in-place.","Assume that no conflicts.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","","","","Mention that trampoline is not collected by areas.","","","Create an empty MemorySet
","Without kernel stacks.","Returns the complement of this set of flags.","","","","Remove all MapArea
","Check PageTable running correctly","Removes the specified flags in-place.","Remove MapArea
that starts with start_vpn
","","","Inserts or removes the specified flags depending on the …","","","","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get pagetable root_ppn
","Translate throuth pagetable","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","","","","","","page table entry structure","","","","","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","PTE","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","Return an empty PTE","","Check PTE executable","","","","Return 10bit flag","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","Temporarily used to get arguments from user space.","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Check PTE valid","","","Create a PTE from ppn","Returns the complement of this set of flags.","","Return 44bit ppn","Check PTE readable","Removes the specified flags in-place.","","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","","","","translate a pointer to a mutable u8 Vec through page table","translate a generic through page table and return a …","translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","","","","","","Returns the union of between the flags in self
and other
.","","Check PTE writable","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","use sbi call to set timer","use sbi call to shutdown the kernel","Wrap a static data structure inside it so that we are able …","inner data","Uniprocessor interior mutability primitives","Wrap a static data structure inside it so that we are able …","","","Exclusive access inner data in UPSafeCell. Panic if the …","Returns the argument unchanged.","inner data","Calls U::from(self)
.","User is responsible to guarantee that inner struct is only …","","","","","","","","","","","","","File and filesystem-related syscalls","","handle syscall exception with syscall_id
and other …","","","","","","","","","","If there is not a child process whose pid is same as …","","pid of usertests app in make run TEST=1","Globle process that init user shell","Kernelstack for app","Pid Allocator struct","Bind pid lifetime to PidHandle
","Processor management structure","task context structure containing some registers","A array of TaskControlBlock
that is thread-safe","","Add init process to the manager","Interface offered to add task","","","Implementation of TaskContext
","","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Exit the current ‘Running’ task and run the next task …","Interface offered to pop the first task","Returns the argument unchanged.","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Implementation of TaskManager
","Implementation of PidAllocator
","","Allocate a pid from PID_ALLOCATOR","Implementation of Processor
and Intersection of control …","return address ( e.g. __restore ) of __switch ASM function","","","The main part of process execution and scheduling Loop …","s0-11 register, callee saved","Return to idle control flow for new scheduling","kernel stack pointer of app","Suspend the current ‘Running’ task and run the next …","Wrap switch.S
as a function","Take the current task,leaving a None in its place","Implementation of TaskControlBlock
","","","","task context structure containing some registers","","","Returns the argument unchanged.","set Task Context{__restore ASM funciton: trap_return, sp: …","Calls U::from(self)
.","return address ( e.g. __restore ) of __switch ASM function","s0-11 register, callee saved","kernel stack pointer of app","","","","init task context","","A array of TaskControlBlock
that is thread-safe","","Add a task to TaskManager
","Interface offered to add task","","","","","","Remove the first task and return it,or None
if TaskManager
…","Interface offered to pop the first task","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Creat an empty TaskManager","","","","","","","","Kernelstack for app","","Pid Allocator struct","Bind pid lifetime to PidHandle
","","Allocate a pid","","","","","","","","","","Recycle a pid","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get the value on the top of kernelstack","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Return (bottom, top) of a kernel stack in kernel space.","Create an empty PidAllocator
","Create a kernelstack from pid","","Allocate a pid from PID_ALLOCATOR","Push a value on top of kernelstack","","","","","","","","","","","","","","","Processor management structure","","","","","","Get current task in cloning semanteme","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Returns the argument unchanged.","Returns the argument unchanged.","Get mutable reference to idle_task_cx
","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Calls U::from(self)
.","Create an empty Processor","The main part of process execution and scheduling Loop …","Return to idle control flow for new scheduling","Get current task in moving semanteme","Take the current task,leaving a None in its place","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","","get current time","get current time in microseconds","set the next timer interrupt","trap context structure containing sstatus, sepc and …","Implementation of TrapContext
","enable timer interrupt in sie CSR","initialize CSR stvec
as the entry of __alltraps
","Addr of Page Table","kernel stack","CSR sepc","","","CSR sstatus ","Unimplement: traps/interrupts/exceptions from kernel mode …","handle an interrupt, exception, or system call from user …","Addr of trap_handler function","set the new addr of __restore asm function in TRAMPOLINE …","general regs[0..31]","trap context structure containing sstatus, sepc and …","init app context","","","Returns the argument unchanged.","Calls U::from(self)
.","Addr of Page Table","kernel stack","CSR sepc","set stack pointer to x_2 reg (sp)","CSR sstatus ","Addr of trap_handler function","","","","general regs[0..31]"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,0,6,6,6,6,0,0,10,10,10,10,10,0,0,0,10,0,10,10,10,0,0,0,0,0,0,0,0,0,0,0,44,0,39,40,32,0,0,0,0,0,0,39,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,20,34,18,20,21,22,23,34,18,20,21,22,23,18,20,18,20,21,22,23,18,20,21,22,23,18,20,21,22,34,34,18,20,21,22,18,20,18,20,21,22,34,18,18,18,20,20,20,21,21,21,22,22,22,23,21,23,18,21,21,23,22,34,18,20,21,22,23,34,23,67,23,34,23,34,18,20,18,20,21,22,67,23,24,22,18,20,21,22,23,34,18,20,21,22,23,34,18,20,21,22,23,34,18,20,21,22,23,0,0,0,0,0,36,68,35,16,35,36,16,35,36,35,69,68,35,36,16,35,69,16,0,0,0,16,35,36,35,0,16,35,36,68,16,35,16,35,69,16,35,36,16,35,36,16,35,36,0,0,0,0,0,41,41,0,0,0,0,0,40,40,40,40,44,39,40,39,40,40,40,40,40,40,40,40,39,42,44,41,40,39,42,44,41,40,41,40,41,40,40,40,40,42,42,44,40,0,0,0,40,41,40,0,0,40,41,40,40,40,40,40,39,42,44,41,40,42,40,40,40,39,39,40,40,40,39,40,40,39,42,44,41,40,40,40,42,42,42,39,42,42,39,39,40,39,40,39,39,0,40,39,0,0,40,0,0,0,40,40,40,41,40,40,39,39,39,42,44,41,40,39,42,44,41,40,39,42,44,41,40,40,42,42,42,48,48,48,0,0,0,48,48,48,48,48,48,48,48,48,48,48,48,32,48,48,43,48,32,43,48,32,48,32,48,32,48,48,48,48,48,32,48,32,48,43,43,32,48,48,48,48,48,43,43,48,32,48,48,48,48,43,48,48,48,48,43,48,32,48,48,32,43,43,32,48,48,32,32,48,43,48,48,48,48,48,32,48,43,43,43,0,0,0,43,48,32,43,48,32,43,48,32,48,43,32,0,0,0,0,0,37,0,0,37,37,37,37,37,37,37,37,37,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,54,54,0,59,63,0,0,0,54,0,0,54,63,54,0,0,61,0,0,56,57,59,0,56,0,56,0,0,0,0,54,54,54,0,56,56,56,56,56,56,56,56,56,56,56,56,0,0,58,57,0,57,58,57,58,58,57,0,57,58,57,58,57,57,57,58,57,58,57,58,0,0,0,0,60,59,59,55,61,60,59,55,61,60,59,59,60,55,61,59,55,61,60,61,59,55,61,60,0,59,61,61,0,61,59,59,55,61,60,59,55,61,60,59,55,61,60,0,0,64,63,64,63,64,63,63,0,0,0,64,63,64,63,63,63,64,63,0,0,63,0,63,64,63,64,63,64,0,65,65,0,0,0,65,66,52,66,65,52,66,65,66,65,65,65,52,66,52,52,66,65,66,66,66,52,52,52,52,66,65,66,52,66,52,66,52,66,66,65,66,52,66,65,52,66,65,52,66,65,0,0,0,0,0,0,0,0,0,53,53,53,0,0,53,0,0,53,0,53,0,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53],"f":[0,[[],1],0,0,0,0,0,0,0,[[],2],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[-1,-2,[],[]],[3,1],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[[6,7],8],[9,2],0,0,[-1,-2,[],[]],[-1,-2,[],[]],[10,[[11,[7]]]],[-1,-1,[]],[12,[[14,[13]]]],[7,[[15,[[14,[13]]]]]],[[],12],[-1,-2,[],[]],[[],1],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],[[15,[16]]]],0,0,[[],1],0,0,0,0,[[],1],[[12,13,12],[[11,[[14,[13]]]]]],[12,-1,[]],[[12,13],17],0,0,0,0,0,0,0,0,0,0,0,0,[18,19],[20,19],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[18,21],[20,22],[18,18],[20,20],[21,21],[22,22],[[[23,[-1]]],[[23,[-1]]],[24,25,26,27,28,29]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[18,18],30],[[20,20],30],[[21,21],30],[[22,22],30],0,0,[[18,18],19],[[20,20],19],[[21,21],19],[[22,22],19],[18,21],[20,22],[[18,31],8],[[20,31],8],[[21,31],8],[[22,31],8],[-1,-1,[]],[-1,-1,[]],[21,18],[12,18],[12,20],[22,20],[-1,-1,[]],[12,21],[-1,-1,[]],[18,21],[-1,-1,[]],[12,22],[20,22],[-1,-1,[]],[21,[[14,[13]]]],[[[23,[-1]]],-1,[24,25,26,27,28]],[18,-1,[]],[21,-1,[]],[21,[[14,[32]]]],[[[23,[-1]]],-1,[24,25,26,27,28]],[22,[[33,[12]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[23,[-1]]],[],[24,25,26,27,28]],0,0,[[-1,-1],[[34,[-1]]],[24,25,26,27,28]],[[-1,-1],[[23,[-1]]],[24,25,26,27,28]],[[[34,[-1]]],15,[24,25,26,27,28]],[18,12],[20,12],[[18,18],[[15,[30]]]],[[20,20],[[15,[30]]]],[[21,21],[[15,[30]]]],[[22,22],[[15,[30]]]],0,0,[-1,1,[]],[22,1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,0,[-1,[[15,[21]]],[]],[35,[[15,[21]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,0,[[-1,21],1,[]],[[35,21],1],[36,[[37,[35]]]],[16,1],0,0,[[16,31],8],[[],[[15,[16]]]],[[],1],[21,1],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[[35,21,21],1],[[],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],-1,[]],[21,16],[[],35],0,0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,[38,2],[[],1],[[],1],0,0,0,0,0,0,0,0,0,0,0,0,[39,1],[[],40],0,[[40,40],40],[[40,40],1],[[40,40],40],[[40,40],1],[40,13],0,[[40,40],40],[[40,40],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[41,41],[40,40],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[40,40],30],[40,40],[[40,40],19],[[42,43,[14,[13]]],1],0,[44,[[45,[[37,[39]]]]]],[[40,40],40],0,0,0,[[],40],[[41,41],19],[[40,40],19],0,0,[[40,-1],1,46],[[41,31],8],[[40,31],8],[[40,31],8],[[40,31],8],[[40,31],8],[[40,31],8],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[42,42],[13,[[15,[40]]]],[13,40],[13,40],[[[14,[13]]],[[1,[39,12,12]]]],[39,39],[-1,40,46],[[40,-1],1,47],[[40,40],1],[[39,20,20,40],1],[[40,40],40],[[40,40],19],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[40,19],[40,19],[[42,43],1],[[42,43,22],1],0,[39,1],0,[[20,20,41,40],42],[[],39],[[],39],[40,40],0,[[40,40],[[15,[30]]]],[[39,42,[15,[[14,[13]]]]],1],[39,1],[[],1],[[40,40],1],[[39,22],1],0,0,[[40,40,19],1],0,0,0,[[40,40],40],[[40,40],1],[[40,40],40],[-1,-2,[],[]],[-1,-2,[],[]],[[40,40],1],[39,12],[[39,22],[[15,[32]]]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[[40,40],40],[[42,43],1],[[42,43,22],1],0,0,0,0,0,0,0,0,0,0,0,0,[[],48],[[48,48],48],[[48,48],1],[[48,48],48],[[48,48],1],[48,13],0,0,[[48,48],48],[[48,48],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[48,48],[32,32],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[48,48],30],[48,48],[[48,48],19],[[48,48],48],[[],48],[[],32],[[48,48],19],[32,19],[[48,-1],1,46],[[43,22],[[15,[32]]]],[[43,22],[[15,[32]]]],[32,48],[[48,31],8],[[48,31],8],[[48,31],8],[[48,31],8],[[48,31],8],0,[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[13,[[15,[48]]]],[13,48],[13,48],[-1,48,46],[12,43],[[48,-1],1,47],[[48,48],1],[[48,48],48],[[48,48],19],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[48,19],[48,19],[32,19],[[43,22,21,48],1],[[],43],[[21,48],32],[48,48],[[48,48],[[15,[30]]]],[32,21],[32,19],[[48,48],1],0,[[48,48,19],1],[[48,48],48],[[48,48],1],[[48,48],48],[-1,-2,[],[]],[-1,-2,[],[]],[[48,48],1],[43,12],[[43,22],[[15,[32]]]],[[43,20],[[15,[18]]]],[[12,13,12],[[11,[[14,[13]]]]]],[12,-1,[]],[[12,13],17],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[[48,48],48],[[43,22],1],[32,19],[[],12],[12,1],[12,1],[19,2],0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[[[37,[-1]]],[[49,[-1]]],[]],[-1,-1,[]],0,[-1,-2,[],[]],[-1,[[37,[-1]]],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0,0,0,0,0,0,0,0,0,0,0,[[12,[33,[12]]],50],0,0,[[12,13,12],50],[[12,13,12],50],[13,50],[51,2],[[],50],[[],50],[[],50],[[50,51],50],[[],50],0,0,0,0,0,0,0,0,0,[[],1],[[[45,[52]]],1],[-1,-2,[],[]],[-1,-2,[],[]],0,0,0,[[],[[15,[[45,[52]]]]]],[[],53],[[],12],[54,[[45,[52]]]],[51,1],[[],[[15,[[45,[52]]]]]],[-1,-1,[]],0,[-1,-2,[],[]],0,0,0,[[],55],0,0,0,0,[[],1],0,[56,1],0,[[],1],0,[[],[[15,[[45,[52]]]]]],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[12,56],[-1,-2,[],[]],0,0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[[],56],0,0,0,[[57,[45,[52]]],1],[[[45,[52]]],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[58,[[37,[57]]]],[57,[[15,[[45,[52]]]]]],[[],[[15,[[45,[52]]]]]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],57],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,[59,55],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,[[59,12],1],[60,[[37,[59]]]],[55,1],[61,1],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[61,12],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[12,[[1,[12,12]]]],[[],59],[55,61],0,[[],55],[[61,-1],[],62],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[63,[[15,[[45,[52]]]]]],0,[[],[[15,[[45,[52]]]]]],[[],53],[[],12],[64,[[37,[63]]]],[-1,-1,[]],[-1,-1,[]],[63,56],0,[-1,-2,[],[]],[-1,-2,[],[]],[[],63],[[],1],[56,1],[63,[[15,[[45,[52]]]]]],[[],[[15,[[45,[52]]]]]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,[65,65],[[-1,-2],1,[],[]],[[65,65],19],[[52,[14,[13]]],1],0,[[[45,[52]]],[[45,[52]]]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[66,65],[66,53],[66,12],[52,12],0,[52,[[49,[66]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[66,19],0,0,[[[14,[13]]],52],0,0,0,0,[-1,-2,[],[]],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,[[],12],[[],12],[[],1],0,0,[[],1],[[],1],0,0,0,[[],1],[[],1],0,[[],2],[[],2],0,[[],2],0,0,[[12,12,12,12,12],53],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[-1,-2,[],[]],0,0,0,[[53,12],1],0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0],"c":[],"p":[[15,"tuple"],[15,"never"],[3,"Arguments",777],[4,"Result",778],[3,"TypeId",779],[3,"Stdout",29],[15,"str"],[6,"Result",777],[3,"PanicInfo",780],[3,"APP_NAMES",40],[3,"Vec",781],[15,"usize"],[15,"u8"],[15,"slice"],[4,"Option",782],[3,"FrameTracker",203],[3,"String",783],[3,"PhysAddr",82],[15,"bool"],[3,"VirtAddr",82],[3,"PhysPageNum",82],[3,"VirtPageNum",82],[3,"SimpleRange",82],[8,"StepByOne",82],[8,"Copy",784],[8,"PartialEq",785],[8,"PartialOrd",785],[8,"Debug",777],[8,"Clone",786],[4,"Ordering",785],[3,"Formatter",777],[3,"PageTableEntry",389],[15,"array"],[3,"SimpleRangeIterator",82],[3,"StackFrameAllocator",203],[3,"FRAME_ALLOCATOR",203],[3,"UPSafeCell",497],[3,"Layout",787],[3,"MemorySet",257],[3,"MapPermission",257],[4,"MapType",257],[3,"MapArea",257],[3,"PageTable",389],[3,"KERNEL_SPACE",257],[3,"Arc",788],[8,"IntoIterator",789],[8,"Hasher",790],[3,"PTEFlags",389],[3,"RefMut",791],[15,"isize"],[15,"i32"],[3,"TaskControlBlock",690],[3,"TrapContext",761],[3,"INITPROC",531],[3,"PidHandle",612],[3,"TaskContext",575],[3,"TaskManager",588],[3,"TASK_MANAGER",588],[3,"PidAllocator",612],[3,"PID_ALLOCATOR",612],[3,"KernelStack",612],[8,"Sized",784],[3,"Processor",659],[3,"PROCESSOR",659],[4,"TaskStatus",690],[3,"TaskControlBlockInner",690],[6,"VPNRange",82],[8,"FrameAllocator",203],[6,"FrameAllocatorImpl",203]]}\
}');
if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
diff --git a/ch5/search.js b/ch5/search.js
deleted file mode 100644
index d35a7db8..00000000
--- a/ch5/search.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("titles").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb}else if(nb!==0){printTab(0)}}const levenshtein_row2=[];function levenshtein(s1,s2){if(s1===s2){return 0}const s1_len=s1.length,s2_len=s2.length;if(s1_len&&s2_len){let i1=0,i2=0,a,b,c,c2;const row=levenshtein_row2;while(i1-".indexOf(c)!==-1}function isStopCharacter(c){return isWhitespace(c)||isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){for(let i=0,len=itemTypes.length;i0){throw new Error("Cannot use literal search when there is more than one element")}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw new Error("Unclosed `\"`")}else if(parserState.userQuery[end]!=="\""){throw new Error(`Unexpected \`${parserState.userQuery[end]}\` in a string element`)}else if(start===end){throw new Error("Cannot have empty string element")}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","||isWhitespaceCharacter(c)}function isWhitespaceCharacter(c){return c===" "||c==="\t"}function createQueryElement(query,parserState,name,generics,isInGenerics){if(name==="*"||(name.length===0&&generics.length===0)){return}if(query.literalSearch&&parserState.totalElems-parserState.genericsElems>0){throw new Error("You cannot have more than one element if you use quotes")}const pathSegments=name.split("::");if(pathSegments.length>1){for(let i=0,len=pathSegments.length;i=end){throw new Error("Found generics without a path")}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;while(parserState.pos"){extra="`<`"}else if(endChar===""){extra="`->`"}throw new Error("Unexpected `"+c+"` after "+extra)}if(!foundStopChar){if(endChar!==""){throw new Error(`Expected \`,\`, \` \` or \`${endChar}\`, found \`${c}\``)}throw new Error(`Expected \`,\` or \` \`, found \`${c}\``)}const posBefore=parserState.pos;getNextElem(query,parserState,elems,endChar===">");if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}parserState.pos+=1}function checkExtraTypeFilterCharacters(parserState){const query=parserState.userQuery;for(let pos=0;pos"){if(isReturnArrow(parserState)){break}throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`)}throw new Error(`Unexpected \`${c}\``)}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw new Error("Unexpected `:`")}if(query.elems.length===0){throw new Error("Expected type filter before `:`")}else if(query.elems.length!==1||parserState.totalElems!==1){throw new Error("Unexpected `:`")}else if(query.literalSearch){throw new Error("You cannot use quotes on type filter")}checkExtraTypeFilterCharacters(parserState);parserState.typeFilter=query.elems.pop().name;parserState.pos+=1;parserState.totalElems=0;query.literalSearch=false;foundStopChar=true;continue}if(!foundStopChar){if(parserState.typeFilter!==null){throw new Error(`Expected \`,\`, \` \` or \`->\`, found \`${c}\``)}throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``)}before=query.elems.length;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}while(parserState.pos`")}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),typeFilter:NO_TYPE_FILTER,elems:[],returned:[],foundElems:0,literalSearch:false,error:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);if(parserState.typeFilter!==null){let typeFilter=parserState.typeFilter;if(typeFilter==="const"){typeFilter="constant"}query.typeFilter=itemTypeFromName(typeFilter)}}catch(err){query=newParsedQuery(userQuery);query.error=err.message;query.typeFilter=-1;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others={},results_in_args={},results_returned={};function transformResults(results){const duplicates={};const out=[];for(const result of results){if(result.id>-1){const obj=searchIndex[result.id];obj.lev=result.lev;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates[obj.fullPath]){continue}duplicates[obj.fullPath]=true;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){const userQuery=parsedQuery.userQuery;const ar=[];for(const entry in results){if(hasOwnPropertyRustdoc(results,entry)){const result=results[entry];result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};ar.push(result)}}results=ar;if(results.length===0){return[]}results.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.lev);b=(bbb.lev);if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of results){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(results)}function checkGenerics(row,elem,defaultLev){if(row.generics.length===0){return elem.generics.length===0?defaultLev:MAX_LEV_DISTANCE+1}else if(row.generics.length>0&&row.generics[0].name===null){return checkGenerics(row.generics[0],elem,defaultLev)}let elem_name;if(elem.generics.length>0&&row.generics.length>=elem.generics.length){const elems=Object.create(null);for(const entry of row.generics){elem_name=entry.name;if(elem_name===""){if(checkGenerics(entry,elem,MAX_LEV_DISTANCE+1)!==0){return MAX_LEV_DISTANCE+1}continue}if(elems[elem_name]===undefined){elems[elem_name]=0}elems[elem_name]+=1}for(const generic of elem.generics){let match=null;if(elems[generic.name]){match=generic.name}else{for(elem_name in elems){if(!hasOwnPropertyRustdoc(elems,elem_name)){continue}if(elem_name===generic){match=elem_name;break}}}if(match===null){return MAX_LEV_DISTANCE+1}elems[match]-=1;if(elems[match]===0){delete elems[match]}}return 0}return MAX_LEV_DISTANCE+1}function checkIfInGenerics(row,elem){let lev=MAX_LEV_DISTANCE+1;for(const entry of row.generics){lev=Math.min(checkType(entry,elem,true),lev);if(lev===0){break}}return lev}function checkType(row,elem,literalSearch){if(row.name===null){if(row.generics.length>0){return checkIfInGenerics(row,elem)}return MAX_LEV_DISTANCE+1}let lev=levenshtein(row.name,elem.name);if(literalSearch){if(lev!==0){if(elem.generics.length===0){const checkGeneric=row.generics.length>0;if(checkGeneric&&row.generics.findIndex(tmp_elem=>tmp_elem.name===elem.name)!==-1){return 0}}return MAX_LEV_DISTANCE+1}else if(elem.generics.length>0){return checkGenerics(row,elem,MAX_LEV_DISTANCE+1)}return 0}else if(row.generics.length>0){if(elem.generics.length===0){if(lev===0){return 0}lev=checkIfInGenerics(row,elem);return lev+0.5}else if(lev>MAX_LEV_DISTANCE){return checkIfInGenerics(row,elem)}else{const tmp_lev=checkGenerics(row,elem,lev);if(tmp_lev>MAX_LEV_DISTANCE){return MAX_LEV_DISTANCE+1}return(tmp_lev+lev)/2}}else if(elem.generics.length>0){return MAX_LEV_DISTANCE+1}return lev}function findArg(row,elem,typeFilter){let lev=MAX_LEV_DISTANCE+1;if(row&&row.type&&row.type.inputs&&row.type.inputs.length>0){for(const input of row.type.inputs){if(!typePassesFilter(typeFilter,input.ty)){continue}lev=Math.min(lev,checkType(input,elem,parsedQuery.literalSearch));if(lev===0){return 0}}}return parsedQuery.literalSearch?MAX_LEV_DISTANCE+1:lev}function checkReturned(row,elem,typeFilter){let lev=MAX_LEV_DISTANCE+1;if(row&&row.type&&row.type.output.length>0){const ret=row.type.output;for(const ret_ty of ret){if(!typePassesFilter(typeFilter,ret_ty.ty)){continue}lev=Math.min(lev,checkType(ret_ty,elem,parsedQuery.literalSearch));if(lev===0){return 0}}}return parsedQuery.literalSearch?MAX_LEV_DISTANCE+1:lev}function checkPath(contains,ty){if(contains.length===0){return 0}let ret_lev=MAX_LEV_DISTANCE+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return MAX_LEV_DISTANCE+1}for(let i=0;ilength){break}let lev_total=0;let aborted=false;for(let x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(!aborted){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES[filterCrates]&&ALIASES[filterCrates][lowerQuery]){const query_aliases=ALIASES[filterCrates][lowerQuery];for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{Object.keys(ALIASES).forEach(crate=>{if(ALIASES[crate][lowerQuery]){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=ALIASES[crate][lowerQuery];for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}})}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,lev){if(lev===0||(!parsedQuery.literalSearch&&lev<=MAX_LEV_DISTANCE)){if(results[fullId]!==undefined){const result=results[fullId];if(result.dontValidate||result.lev<=lev){return}}results[fullId]={id:id,index:index,dontValidate:parsedQuery.literalSearch,lev:lev,}}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let lev,lev_add=0,index=-1;const fullId=row.id;const in_args=findArg(row,elem,parsedQuery.typeFilter);const returned=checkReturned(row,elem,parsedQuery.typeFilter);addIntoResults(results_in_args,fullId,pos,index,in_args);addIntoResults(results_returned,fullId,pos,index,returned);if(!typePassesFilter(parsedQuery.typeFilter,row.ty)){return}const searchWord=searchWords[pos];if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,-1,0)}return}if(elem.name.length===0){if(row.type!==null){lev=checkGenerics(row.type,elem,MAX_LEV_DISTANCE+1);addIntoResults(results_others,fullId,pos,index,lev)}return}if(elem.fullPath.length>1){lev=checkPath(elem.pathWithoutLast,row);if(lev>MAX_LEV_DISTANCE||(parsedQuery.literalSearch&&lev!==0)){return}else if(lev>0){lev_add=lev/10}}if(searchWord.indexOf(elem.pathLast)>-1||row.normalizedName.indexOf(elem.pathLast)>-1){index=row.normalizedName.indexOf(elem.pathLast)}lev=levenshtein(searchWord,elem.pathLast);if(lev>0&&elem.pathLast.length>2&&searchWord.indexOf(elem.pathLast)>-1){if(elem.pathLast.length<6){lev=1}else{lev=0}}lev+=lev_add;if(lev>MAX_LEV_DISTANCE){return}else if(index!==-1&&elem.fullPath.length<2){lev-=1}if(lev<0){lev=0}addIntoResults(results_others,fullId,pos,index,lev)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let totalLev=0;let nbLev=0;function checkArgs(elems,callback){for(const elem of elems){const lev=callback(row,elem,NO_TYPE_FILTER);if(lev<=1){nbLev+=1;totalLev+=lev}else{return false}}return true}if(!checkArgs(parsedQuery.elems,findArg)){return}if(!checkArgs(parsedQuery.returned,checkReturned)){return}if(nbLev===0){return}const lev=Math.round(totalLev/nbLev);addIntoResults(results,row.id,pos,0,lev)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||levenshtein(name,key)<=MAX_LEV_DISTANCE)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#titles > button").item(searchState.currentTab);if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){const h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];length+=1;let extra="";if(type==="primitive"){extra=" (primitive type)"}else if(type==="keyword"){extra=" (keyword)"}const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const wrapper=document.createElement("div");const resultName=document.createElement("div");resultName.className="result-name";if(item.is_alias){const alias=document.createElement("span");alias.className="alias";const bold=document.createElement("b");bold.innerText=item.alias;alias.appendChild(bold);alias.insertAdjacentHTML("beforeend"," - see ");resultName.appendChild(alias)}resultName.insertAdjacentHTML("beforeend",item.displayPath+""+name+extra+"");wrapper.appendChild(resultName);const description=document.createElement("div");description.className="desc";const spanDesc=document.createElement("span");spanDesc.insertAdjacentHTML("beforeend",item.desc);description.appendChild(spanDesc);wrapper.appendChild(description);link.appendChild(wrapper);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?
"+"Or try looking in one of these:- The Rust Reference "+" for technical details about the language.
- Rust By "+"Example for expository code examples.
- The Rust Book for "+"introductions to language features and the language itself.
- Docs.rs for documentation of crates released on"+" crates.io.
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==searchState.loadingText))){const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in "}let typeFilter="";if(results.query.typeFilter!==NO_TYPE_FILTER){typeFilter=" (type: "+escape(itemTypes[results.query.typeFilter])+")"}let output=""+`Results for ${escape(results.query.userQuery)}`+`${typeFilter}
${crates}`;if(results.query.error!==null){output+=`Query parser error: "${results.query.error}".
`;output+=""+makeTabHeader(0,"In Names",ret_others[1])+"";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+=""+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+""}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+=""+makeTabHeader(0,signatureTabTitle,ret_others[1])+"";currentTab=0}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("titles").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function search(e,forced){const params=searchState.getQueryStringParams();const query=parseQuery(searchState.input.value.trim());if(e){e.preventDefault()}if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}let filterCrates=getFilterCrates();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";if(browserSupportsHistoryApi()){const newURL=buildUrl(query.original,filterCrates);if(!history.state&&!params.search){history.pushState(null,"",newURL)}else{history.replaceState(null,"",newURL)}}showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}return{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:generics,}})}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){const pathIndex=functionSearchType[INPUTS_DATA];inputs=[{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];output=[{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];let i,word;let currentIndex=0;let id=0;for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=crateCorpus.q;const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;for(i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){ALIASES[crate]=Object.create(null);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}if(!hasOwnPropertyRustdoc(ALIASES[crate],alias_name)){ALIASES[crate][alias_name]=[]}for(const local_alias of aliases[alias_name]){ALIASES[crate][alias_name].push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){if(browserSupportsHistoryApi()){history.replaceState(null,window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="All crates"){const params=searchState.getQueryStringParams();const query=searchState.input.value.trim();if(!history.state&&!params.search){history.pushState(null,"",buildUrl(query,null))}else{history.replaceState(null,"",buildUrl(query,null))}}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})()
\ No newline at end of file
diff --git a/ch5/settings.css b/ch5/settings.css
deleted file mode 100644
index a142e14f..00000000
--- a/ch5/settings.css
+++ /dev/null
@@ -1 +0,0 @@
-.setting-line{margin:0.6em 0 0.6em 0.3em;position:relative;}.setting-line .choices{display:flex;flex-wrap:wrap;}.setting-line .radio-line input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:1px solid;outline:none;-webkit-appearance:none;cursor:pointer;border-radius:50%;}.setting-line .radio-line input+span{padding-bottom:1px;}.radio-line .setting-name{width:100%;}.radio-line .choice{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:flex;align-items:center;cursor:pointer;}.radio-line .choice+.choice{margin-left:0.5em;}.toggle{position:relative;width:100%;margin-right:20px;display:flex;align-items:center;cursor:pointer;}.toggle input{opacity:0;position:absolute;}.slider{position:relative;width:45px;min-width:45px;display:block;height:28px;margin-right:20px;cursor:pointer;background-color:#ccc;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;transition:.3s;}input:checked+.slider:before{transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;}#settings .setting-line{margin:1.2em 0.6em;}
\ No newline at end of file
diff --git a/ch5/settings.html b/ch5/settings.html
index ecb27c50..44145da1 100644
--- a/ch5/settings.html
+++ b/ch5/settings.html
@@ -1 +1 @@
-Rustdoc settings Rustdoc settings
Back
\ No newline at end of file
+Rustdoc settings Rustdoc settings
Back
\ No newline at end of file
diff --git a/ch5/settings.js b/ch5/settings.js
deleted file mode 100644
index df27fca4..00000000
--- a/ch5/settings.js
+++ /dev/null
@@ -1,11 +0,0 @@
-"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":case"use-system-theme":updateSystemTheme();updateLightAndDark();break}}function handleKey(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey){return}switch(getVirtualKey(ev)){case"Enter":case"Return":case"Space":ev.target.checked=!ev.target.checked;ev.preventDefault();break}}function showLightAndDark(){addClass(document.getElementById("theme").parentElement,"hidden");removeClass(document.getElementById("preferred-light-theme").parentElement,"hidden");removeClass(document.getElementById("preferred-dark-theme").parentElement,"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme").parentElement,"hidden");addClass(document.getElementById("preferred-dark-theme").parentElement,"hidden");removeClass(document.getElementById("theme").parentElement,"hidden")}function updateLightAndDark(){if(getSettingValue("use-system-theme")!=="false"){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.getElementsByClassName("slider"),elem=>{const toggle=elem.previousElementSibling;const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)};toggle.onkeyup=handleKey;toggle.onkeyrelease=handleKey});onEachLazy(settingsElement.getElementsByClassName("select-wrapper"),elem=>{const select=elem.getElementsByTagName("select")[0];const settingId=select.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){select.value=settingValue}select.onchange=function(){changeSetting(this.id,this.value)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;const settingValue=getSettingValue(settingId);if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){output+="";const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\
- ${setting_name}\
- `;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";output+=``});output+=""}else{const checked=setting["default"]===true?" checked":"";output+=``}output+=""}return output}function buildSettingsPage(){const themes=getVar("themes").split(",");const settings=[{"name":"Use system theme","js_name":"use-system-theme","default":true,},{"name":"Theme","js_name":"theme","default":"light","options":themes,},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":themes,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":themes,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`${buildSettingsPageSections(settings)}`;const el=document.createElement(elementKind);el.id="settings";el.className="popover";el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(event){if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hidePopoverMenus();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})()
\ No newline at end of file
diff --git a/ch5/source-script.js b/ch5/source-script.js
deleted file mode 100644
index e0fac073..00000000
--- a/ch5/source-script.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(function(){const rootPath=document.getElementById("rustdoc-vars").attributes["data-root-path"].value;let oldScrollPosition=0;const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;function closeSidebarIfMobile(){if(window.innerWidth"){if(window.innerWidth";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSourceSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="source-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(key=>{sourcesIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSourceLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("span"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSourceHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSourceLines(match)}});onEachLazy(document.getElementsByClassName("line-numbers"),el=>{el.addEventListener("click",handleSourceHighlight)});highlightSourceLines();window.createSourceSidebar=createSourceSidebar})()
\ No newline at end of file
diff --git a/ch5/source-files.js b/ch5/src-files.js
similarity index 88%
rename from ch5/source-files.js
rename to ch5/src-files.js
index 5704744f..ed981ad2 100644
--- a/ch5/source-files.js
+++ b/ch5/src-files.js
@@ -1,4 +1,4 @@
-var sourcesIndex = JSON.parse('{\
+var srcIndex = JSON.parse('{\
"os":["",[["boards",[],["qemu.rs"]],["mm",[],["address.rs","frame_allocator.rs","heap_allocator.rs","memory_set.rs","mod.rs","page_table.rs"]],["sync",[],["mod.rs","up.rs"]],["syscall",[],["fs.rs","mod.rs","process.rs"]],["task",[],["context.rs","manager.rs","mod.rs","pid.rs","processor.rs","switch.rs","task.rs"]],["trap",[],["context.rs","mod.rs"]]],["config.rs","console.rs","lang_items.rs","loader.rs","main.rs","sbi.rs","timer.rs"]]\
}');
-createSourceSidebar();
+createSrcSidebar();
diff --git a/ch5/src/os/boards/qemu.rs.html b/ch5/src/os/boards/qemu.rs.html
index 178b5814..5c5fbbda 100644
--- a/ch5/src/os/boards/qemu.rs.html
+++ b/ch5/src/os/boards/qemu.rs.html
@@ -1,18 +1,17 @@
-qemu.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-
//! Constants used in rCore for qemu
+qemu.rs - source //! Constants used in rCore for qemu
-pub const CLOCK_FREQ: usize = 12500000;
-pub const MEMORY_END: usize = 0x81000000;
+pub const CLOCK_FREQ: usize = 12500000;
+pub const MEMORY_END: usize = 0x81000000;
-pub const MMIO: &[(usize, usize)] = &[
- (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine
-];
-
-
\ No newline at end of file
+pub const MMIO: &[(usize, usize)] = &[
+ (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine
+];
+
\ No newline at end of file
diff --git a/ch5/src/os/config.rs.html b/ch5/src/os/config.rs.html
index 4b18ced4..5fc8e651 100644
--- a/ch5/src/os/config.rs.html
+++ b/ch5/src/os/config.rs.html
@@ -1,26 +1,25 @@
-config.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-
//! Constants used in rCore
-pub const USER_STACK_SIZE: usize = 4096 * 2;
-pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
-pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
+config.rs - source //! Constants used in rCore
+pub const USER_STACK_SIZE: usize = 4096 * 2;
+pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
+pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
-pub const PAGE_SIZE: usize = 0x1000;
-pub const PAGE_SIZE_BITS: usize = 0xc;
+pub const PAGE_SIZE: usize = 0x1000;
+pub const PAGE_SIZE_BITS: usize = 0xc;
-pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1;
-pub const TRAP_CONTEXT: usize = TRAMPOLINE - PAGE_SIZE;
+pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1;
+pub const TRAP_CONTEXT: usize = TRAMPOLINE - PAGE_SIZE;
-pub use crate::board::{CLOCK_FREQ, MEMORY_END, MMIO};
-
-
\ No newline at end of file
+pub use crate::board::{CLOCK_FREQ, MEMORY_END, MMIO};
+
\ No newline at end of file
diff --git a/ch5/src/os/console.rs.html b/ch5/src/os/console.rs.html
index d95c6c36..c1f9f845 100644
--- a/ch5/src/os/console.rs.html
+++ b/ch5/src/os/console.rs.html
@@ -1,70 +1,69 @@
-console.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-
//! SBI console driver, for text output
-use crate::sbi::console_putchar;
-use core::fmt::{self, Write};
+console.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+
//! SBI console driver, for text output
+use crate::sbi::console_putchar;
+use core::fmt::{self, Write};
-struct Stdout;
+struct Stdout;
-impl Write for Stdout {
- fn write_str(&mut self, s: &str) -> fmt::Result {
- for c in s.chars() {
- console_putchar(c as usize);
+impl Write for Stdout {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for c in s.chars() {
+ console_putchar(c as usize);
}
Ok(())
}
}
-pub fn print(args: fmt::Arguments) {
- Stdout.write_fmt(args).unwrap();
+pub fn print(args: fmt::Arguments) {
+ Stdout.write_fmt(args).unwrap();
}
-#[macro_export]
-/// print string macro
-macro_rules! print {
- ($fmt: literal $(, $($arg: tt)+)?) => {
- $crate::console::print(format_args!($fmt $(, $($arg)+)?));
+#[macro_export]
+/// print string macro
+macro_rules! print {
+ ($fmt: literal $(, $($arg: tt)+)?) => {
+ $crate::console::print(format_args!($fmt $(, $($arg)+)?));
}
}
-#[macro_export]
-/// println string macro
-macro_rules! println {
- ($fmt: literal $(, $($arg: tt)+)?) => {
- $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
+#[macro_export]
+/// println string macro
+macro_rules! println {
+ ($fmt: literal $(, $($arg: tt)+)?) => {
+ $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/lang_items.rs.html b/ch5/src/os/lang_items.rs.html
index 1343e5be..5fe215bd 100644
--- a/ch5/src/os/lang_items.rs.html
+++ b/ch5/src/os/lang_items.rs.html
@@ -1,40 +1,39 @@
-lang_items.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-
//! The panic handler
-use crate::sbi::shutdown;
-use core::panic::PanicInfo;
-use log::*;
+lang_items.rs - source //! The panic handler
+use crate::sbi::shutdown;
+use core::panic::PanicInfo;
+use log::*;
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
- if let Some(location) = info.location() {
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+ if let Some(location) = info.location() {
error!(
"[kernel] Panicked at {}:{} {}",
- location.file(),
- location.line(),
- info.message().unwrap()
+ location.file(),
+ location.line(),
+ info.message().unwrap()
);
- } else {
- error!("[kernel] Panicked: {}", info.message().unwrap());
+ } else {
+ error!("[kernel] Panicked: {}", info.message().unwrap());
}
- shutdown(true)
+ shutdown(true)
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/loader.rs.html b/ch5/src/os/loader.rs.html
index eb0cb95c..c60bc498 100644
--- a/ch5/src/os/loader.rs.html
+++ b/ch5/src/os/loader.rs.html
@@ -1,142 +1,141 @@
-loader.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-
//! Loading user applications into memory
+loader.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+
//! Loading user applications into memory
-/// Get the total number of applications.
-use alloc::vec::Vec;
-use lazy_static::*;
-///get app number
-pub fn get_num_app() -> usize {
- extern "C" {
- fn _num_app();
+/// Get the total number of applications.
+use alloc::vec::Vec;
+use lazy_static::*;
+///get app number
+pub fn get_num_app() -> usize {
+ extern "C" {
+ fn _num_app();
}
- unsafe { (_num_app as usize as *const usize).read_volatile() }
+ unsafe { (_num_app as usize as *const usize).read_volatile() }
}
-/// get applications data
-pub fn get_app_data(app_id: usize) -> &'static [u8] {
- extern "C" {
- fn _num_app();
+/// get applications data
+pub fn get_app_data(app_id: usize) -> &'static [u8] {
+ extern "C" {
+ fn _num_app();
}
- let num_app_ptr = _num_app as usize as *const usize;
- let num_app = get_num_app();
- let app_start = unsafe { core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) };
- assert!(app_id < num_app);
- unsafe {
- core::slice::from_raw_parts(
- app_start[app_id] as *const u8,
- app_start[app_id + 1] - app_start[app_id],
+ let num_app_ptr = _num_app as usize as *const usize;
+ let num_app = get_num_app();
+ let app_start = unsafe { core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) };
+ assert!(app_id < num_app);
+ unsafe {
+ core::slice::from_raw_parts(
+ app_start[app_id] as *const u8,
+ app_start[app_id + 1] - app_start[app_id],
)
}
}
-lazy_static! {
- ///All of app's name
- static ref APP_NAMES: Vec<&'static str> = {
- let num_app = get_num_app();
- extern "C" {
- fn _app_names();
+lazy_static! {
+ ///All of app's name
+ static ref APP_NAMES: Vec<&'static str> = {
+ let num_app = get_num_app();
+ extern "C" {
+ fn _app_names();
}
- let mut start = _app_names as usize as *const u8;
- let mut v = Vec::new();
- unsafe {
- for _ in 0..num_app {
- let mut end = start;
- while end.read_volatile() != b'\0' {
- end = end.add(1);
+ let mut start = _app_names as usize as *const u8;
+ let mut v = Vec::new();
+ unsafe {
+ for _ in 0..num_app {
+ let mut end = start;
+ while end.read_volatile() != b'\0' {
+ end = end.add(1);
}
- let slice = core::slice::from_raw_parts(start, end as usize - start as usize);
- let str = core::str::from_utf8(slice).unwrap();
- v.push(str);
- start = end.add(1);
+ let slice = core::slice::from_raw_parts(start, end as usize - start as usize);
+ let str = core::str::from_utf8(slice).unwrap();
+ v.push(str);
+ start = end.add(1);
}
}
- v
+ v
};
}
-#[allow(unused)]
-///get app data from name
-pub fn get_app_data_by_name(name: &str) -> Option<&'static [u8]> {
- let num_app = get_num_app();
- (0..num_app)
- .find(|&i| APP_NAMES[i] == name)
- .map(get_app_data)
+#[allow(unused)]
+///get app data from name
+pub fn get_app_data_by_name(name: &str) -> Option<&'static [u8]> {
+ let num_app = get_num_app();
+ (0..num_app)
+ .find(|&i| APP_NAMES[i] == name)
+ .map(get_app_data)
}
-///list all apps
-pub fn list_apps() {
+///list all apps
+pub fn list_apps() {
println!("/**** APPS ****");
- for app in APP_NAMES.iter() {
- println!("{}", app);
+ for app in APP_NAMES.iter() {
+ println!("{}", app);
}
println!("**************/");
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/main.rs.html b/ch5/src/os/main.rs.html
index 552958de..dc6fc630 100644
--- a/ch5/src/os/main.rs.html
+++ b/ch5/src/os/main.rs.html
@@ -1,162 +1,161 @@
-main.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-
//! The main module and entrypoint
-//!
-//! Various facilities of the kernels are implemented as submodules. The most
-//! important ones are:
-//!
-//! - [`trap`]: Handles all cases of switching from userspace to the kernel
-//! - [`task`]: Task management
-//! - [`syscall`]: System call handling and implementation
-//! - [`mm`]: Address map using SV39
-//! - [`sync`]:Wrap a static data structure inside it so that we are able to access it without any `unsafe`.
-//!
-//! The operating system also starts in this module. Kernel code starts
-//! executing from `entry.asm`, after which [`rust_main()`] is called to
-//! initialize various pieces of functionality. (See its source code for
-//! details.)
-//!
-//! We then call [`task::run_tasks()`] and for the first time go to
-//! userspace.
+main.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
//! The main module and entrypoint
+//!
+//! Various facilities of the kernels are implemented as submodules. The most
+//! important ones are:
+//!
+//! - [`trap`]: Handles all cases of switching from userspace to the kernel
+//! - [`task`]: Task management
+//! - [`syscall`]: System call handling and implementation
+//! - [`mm`]: Address map using SV39
+//! - [`sync`]:Wrap a static data structure inside it so that we are able to access it without any `unsafe`.
+//!
+//! The operating system also starts in this module. Kernel code starts
+//! executing from `entry.asm`, after which [`rust_main()`] is called to
+//! initialize various pieces of functionality. (See its source code for
+//! details.)
+//!
+//! We then call [`task::run_tasks()`] and for the first time go to
+//! userspace.
-#![deny(missing_docs)]
-#![deny(warnings)]
-#![no_std]
-#![no_main]
-#![feature(panic_info_message)]
-#![feature(alloc_error_handler)]
+#![deny(missing_docs)]
+#![deny(warnings)]
+#![no_std]
+#![no_main]
+#![feature(panic_info_message)]
+#![feature(alloc_error_handler)]
-extern crate alloc;
+extern crate alloc;
-#[macro_use]
-extern crate bitflags;
+#[macro_use]
+extern crate bitflags;
-#[path = "boards/qemu.rs"]
-mod board;
+#[path = "boards/qemu.rs"]
+mod board;
-#[macro_use]
-mod console;
-mod config;
-mod lang_items;
-mod loader;
-pub mod mm;
-mod sbi;
-pub mod sync;
-pub mod syscall;
-pub mod task;
-mod timer;
-pub mod trap;
+#[macro_use]
+mod console;
+mod config;
+mod lang_items;
+mod loader;
+pub mod mm;
+mod sbi;
+pub mod sync;
+pub mod syscall;
+pub mod task;
+mod timer;
+pub mod trap;
-use core::arch::global_asm;
+use core::arch::global_asm;
global_asm!(include_str!("entry.asm"));
global_asm!(include_str!("link_app.S"));
-/// clear BSS segment
-fn clear_bss() {
- extern "C" {
- fn sbss();
- fn ebss();
+/// clear BSS segment
+fn clear_bss() {
+ extern "C" {
+ fn sbss();
+ fn ebss();
}
- unsafe {
- core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
- .fill(0);
+ unsafe {
+ core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
+ .fill(0);
}
}
-#[no_mangle]
-/// the rust entry-point of os
-pub fn rust_main() -> ! {
- clear_bss();
+#[no_mangle]
+/// the rust entry-point of os
+pub fn rust_main() -> ! {
+ clear_bss();
println!("[kernel] Hello, world!");
- mm::init();
- mm::remap_test();
- task::add_initproc();
+ mm::init();
+ mm::remap_test();
+ task::add_initproc();
println!("after initproc!");
- trap::init();
- //trap::enable_interrupt();
- trap::enable_timer_interrupt();
- timer::set_next_trigger();
- loader::list_apps();
- task::run_tasks();
+ trap::init();
+ //trap::enable_interrupt();
+ trap::enable_timer_interrupt();
+ timer::set_next_trigger();
+ loader::list_apps();
+ task::run_tasks();
panic!("Unreachable in rust_main!");
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/address.rs.html b/ch5/src/os/mm/address.rs.html
index e2244fe5..8b6f42f5 100644
--- a/ch5/src/os/mm/address.rs.html
+++ b/ch5/src/os/mm/address.rs.html
@@ -1,552 +1,551 @@
-address.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-
//! Implementation of physical and virtual address and page number.
-use super::PageTableEntry;
-use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
-use core::fmt::{self, Debug, Formatter};
-/// physical address
-const PA_WIDTH_SV39: usize = 56;
-const VA_WIDTH_SV39: usize = 39;
-const PPN_WIDTH_SV39: usize = PA_WIDTH_SV39 - PAGE_SIZE_BITS;
-const VPN_WIDTH_SV39: usize = VA_WIDTH_SV39 - PAGE_SIZE_BITS;
+address.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+
//! Implementation of physical and virtual address and page number.
+use super::PageTableEntry;
+use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
+use core::fmt::{self, Debug, Formatter};
+/// physical address
+const PA_WIDTH_SV39: usize = 56;
+const VA_WIDTH_SV39: usize = 39;
+const PPN_WIDTH_SV39: usize = PA_WIDTH_SV39 - PAGE_SIZE_BITS;
+const VPN_WIDTH_SV39: usize = VA_WIDTH_SV39 - PAGE_SIZE_BITS;
-/// physical address
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct PhysAddr(pub usize);
-/// virtual address
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct VirtAddr(pub usize);
-/// physical page number
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct PhysPageNum(pub usize);
-/// virtual page number
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct VirtPageNum(pub usize);
+/// physical address
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub struct PhysAddr(pub usize);
+/// virtual address
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub struct VirtAddr(pub usize);
+/// physical page number
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub struct PhysPageNum(pub usize);
+/// virtual page number
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub struct VirtPageNum(pub usize);
-/// Debugging
+/// Debugging
-impl Debug for VirtAddr {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("VA:{:#x}", self.0))
+impl Debug for VirtAddr {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("VA:{:#x}", self.0))
}
}
-impl Debug for VirtPageNum {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("VPN:{:#x}", self.0))
+impl Debug for VirtPageNum {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("VPN:{:#x}", self.0))
}
}
-impl Debug for PhysAddr {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("PA:{:#x}", self.0))
+impl Debug for PhysAddr {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("PA:{:#x}", self.0))
}
}
-impl Debug for PhysPageNum {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("PPN:{:#x}", self.0))
+impl Debug for PhysPageNum {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("PPN:{:#x}", self.0))
}
}
-/// T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
-/// T -> usize: T.0
-/// usize -> T: usize.into()
+/// T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
+/// T -> usize: T.0
+/// usize -> T: usize.into()
-impl From<usize> for PhysAddr {
- fn from(v: usize) -> Self {
- Self(v & ((1 << PA_WIDTH_SV39) - 1))
+impl From<usize> for PhysAddr {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << PA_WIDTH_SV39) - 1))
}
}
-impl From<usize> for PhysPageNum {
- fn from(v: usize) -> Self {
- Self(v & ((1 << PPN_WIDTH_SV39) - 1))
+impl From<usize> for PhysPageNum {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << PPN_WIDTH_SV39) - 1))
}
}
-impl From<usize> for VirtAddr {
- fn from(v: usize) -> Self {
- Self(v & ((1 << VA_WIDTH_SV39) - 1))
+impl From<usize> for VirtAddr {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << VA_WIDTH_SV39) - 1))
}
}
-impl From<usize> for VirtPageNum {
- fn from(v: usize) -> Self {
- Self(v & ((1 << VPN_WIDTH_SV39) - 1))
+impl From<usize> for VirtPageNum {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << VPN_WIDTH_SV39) - 1))
}
}
-impl From<PhysAddr> for usize {
- fn from(v: PhysAddr) -> Self {
- v.0
+impl From<PhysAddr> for usize {
+ fn from(v: PhysAddr) -> Self {
+ v.0
+ }
+}
+impl From<PhysPageNum> for usize {
+ fn from(v: PhysPageNum) -> Self {
+ v.0
+ }
+}
+impl From<VirtAddr> for usize {
+ fn from(v: VirtAddr) -> Self {
+ if v.0 >= (1 << (VA_WIDTH_SV39 - 1)) {
+ v.0 | (!((1 << VA_WIDTH_SV39) - 1))
+ } else {
+ v.0
+ }
}
}
-impl From<PhysPageNum> for usize {
- fn from(v: PhysPageNum) -> Self {
- v.0
+impl From<VirtPageNum> for usize {
+ fn from(v: VirtPageNum) -> Self {
+ v.0
+ }
+}
+///
+impl VirtAddr {
+ ///`VirtAddr`->`VirtPageNum`
+ pub fn floor(&self) -> VirtPageNum {
+ VirtPageNum(self.0 / PAGE_SIZE)
+ }
+ ///`VirtAddr`->`VirtPageNum`
+ pub fn ceil(&self) -> VirtPageNum {
+ if self.0 == 0 {
+ VirtPageNum(0)
+ } else {
+ VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
+ }
+ }
+ ///Get page offset
+ pub fn page_offset(&self) -> usize {
+ self.0 & (PAGE_SIZE - 1)
+ }
+ ///Check page aligned
+ pub fn aligned(&self) -> bool {
+ self.page_offset() == 0
+ }
+}
+impl From<VirtAddr> for VirtPageNum {
+ fn from(v: VirtAddr) -> Self {
+ assert_eq!(v.page_offset(), 0);
+ v.floor()
}
}
-impl From<VirtAddr> for usize {
- fn from(v: VirtAddr) -> Self {
- if v.0 >= (1 << (VA_WIDTH_SV39 - 1)) {
- v.0 | (!((1 << VA_WIDTH_SV39) - 1))
- } else {
- v.0
+impl From<VirtPageNum> for VirtAddr {
+ fn from(v: VirtPageNum) -> Self {
+ Self(v.0 << PAGE_SIZE_BITS)
+ }
+}
+impl PhysAddr {
+ ///`PhysAddr`->`PhysPageNum`
+ pub fn floor(&self) -> PhysPageNum {
+ PhysPageNum(self.0 / PAGE_SIZE)
+ }
+ ///`PhysAddr`->`PhysPageNum`
+ pub fn ceil(&self) -> PhysPageNum {
+ if self.0 == 0 {
+ PhysPageNum(0)
+ } else {
+ PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
+ }
+ }
+ ///Get page offset
+ pub fn page_offset(&self) -> usize {
+ self.0 & (PAGE_SIZE - 1)
+ }
+ ///Check page aligned
+ pub fn aligned(&self) -> bool {
+ self.page_offset() == 0
+ }
+}
+impl From<PhysAddr> for PhysPageNum {
+ fn from(v: PhysAddr) -> Self {
+ assert_eq!(v.page_offset(), 0);
+ v.floor()
+ }
+}
+impl From<PhysPageNum> for PhysAddr {
+ fn from(v: PhysPageNum) -> Self {
+ Self(v.0 << PAGE_SIZE_BITS)
+ }
+}
+
+impl VirtPageNum {
+ ///Return VPN 3 level index
+ pub fn indexes(&self) -> [usize; 3] {
+ let mut vpn = self.0;
+ let mut idx = [0usize; 3];
+ for i in (0..3).rev() {
+ idx[i] = vpn & 511;
+ vpn >>= 9;
+ }
+ idx
+ }
+}
+
+impl PhysAddr {
+ ///Get mutable reference to `PhysAddr` value
+ pub fn get_mut<T>(&self) -> &'static mut T {
+ unsafe { (self.0 as *mut T).as_mut().unwrap() }
+ }
+}
+impl PhysPageNum {
+ ///Get `PageTableEntry` on `PhysPageNum`
+ pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
+ let pa: PhysAddr = (*self).into();
+ unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) }
+ }
+ ///
+ pub fn get_bytes_array(&self) -> &'static mut [u8] {
+ let pa: PhysAddr = (*self).into();
+ unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) }
+ }
+ ///
+ pub fn get_mut<T>(&self) -> &'static mut T {
+ let pa: PhysAddr = (*self).into();
+ pa.get_mut()
+ }
+}
+
+pub trait StepByOne {
+ fn step(&mut self);
+}
+impl StepByOne for VirtPageNum {
+ fn step(&mut self) {
+ self.0 += 1;
+ }
+}
+
+#[derive(Copy, Clone)]
+/// a simple range structure for type T
+pub struct SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ l: T,
+ r: T,
+}
+impl<T> SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ pub fn new(start: T, end: T) -> Self {
+ assert!(start <= end, "start {:?} > end {:?}!", start, end);
+ Self { l: start, r: end }
+ }
+ pub fn get_start(&self) -> T {
+ self.l
+ }
+ pub fn get_end(&self) -> T {
+ self.r
+ }
+}
+impl<T> IntoIterator for SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ type Item = T;
+ type IntoIter = SimpleRangeIterator<T>;
+ fn into_iter(self) -> Self::IntoIter {
+ SimpleRangeIterator::new(self.l, self.r)
+ }
+}
+/// iterator for the simple range structure
+pub struct SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ current: T,
+ end: T,
+}
+impl<T> SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ pub fn new(l: T, r: T) -> Self {
+ Self { current: l, end: r }
+ }
+}
+impl<T> Iterator for SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ type Item = T;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.current == self.end {
+ None
+ } else {
+ let t = self.current;
+ self.current.step();
+ Some(t)
}
}
}
-impl From<VirtPageNum> for usize {
- fn from(v: VirtPageNum) -> Self {
- v.0
- }
-}
-///
-impl VirtAddr {
- ///`VirtAddr`->`VirtPageNum`
- pub fn floor(&self) -> VirtPageNum {
- VirtPageNum(self.0 / PAGE_SIZE)
- }
- ///`VirtAddr`->`VirtPageNum`
- pub fn ceil(&self) -> VirtPageNum {
- if self.0 == 0 {
- VirtPageNum(0)
- } else {
- VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
- }
- }
- ///Get page offset
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- ///Check page aligned
- pub fn aligned(&self) -> bool {
- self.page_offset() == 0
- }
-}
-impl From<VirtAddr> for VirtPageNum {
- fn from(v: VirtAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor()
- }
-}
-impl From<VirtPageNum> for VirtAddr {
- fn from(v: VirtPageNum) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
-}
-impl PhysAddr {
- ///`PhysAddr`->`PhysPageNum`
- pub fn floor(&self) -> PhysPageNum {
- PhysPageNum(self.0 / PAGE_SIZE)
- }
- ///`PhysAddr`->`PhysPageNum`
- pub fn ceil(&self) -> PhysPageNum {
- if self.0 == 0 {
- PhysPageNum(0)
- } else {
- PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
- }
- }
- ///Get page offset
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- ///Check page aligned
- pub fn aligned(&self) -> bool {
- self.page_offset() == 0
- }
-}
-impl From<PhysAddr> for PhysPageNum {
- fn from(v: PhysAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor()
- }
-}
-impl From<PhysPageNum> for PhysAddr {
- fn from(v: PhysPageNum) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
-}
-
-impl VirtPageNum {
- ///Return VPN 3 level index
- pub fn indexes(&self) -> [usize; 3] {
- let mut vpn = self.0;
- let mut idx = [0usize; 3];
- for i in (0..3).rev() {
- idx[i] = vpn & 511;
- vpn >>= 9;
- }
- idx
- }
-}
-
-impl PhysAddr {
- ///Get mutable reference to `PhysAddr` value
- pub fn get_mut<T>(&self) -> &'static mut T {
- unsafe { (self.0 as *mut T).as_mut().unwrap() }
- }
-}
-impl PhysPageNum {
- ///Get `PageTableEntry` on `PhysPageNum`
- pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
- let pa: PhysAddr = (*self).into();
- unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) }
- }
- ///
- pub fn get_bytes_array(&self) -> &'static mut [u8] {
- let pa: PhysAddr = (*self).into();
- unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) }
- }
- ///
- pub fn get_mut<T>(&self) -> &'static mut T {
- let pa: PhysAddr = (*self).into();
- pa.get_mut()
- }
-}
-
-pub trait StepByOne {
- fn step(&mut self);
-}
-impl StepByOne for VirtPageNum {
- fn step(&mut self) {
- self.0 += 1;
- }
-}
-
-#[derive(Copy, Clone)]
-/// a simple range structure for type T
-pub struct SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- l: T,
- r: T,
-}
-impl<T> SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- pub fn new(start: T, end: T) -> Self {
- assert!(start <= end, "start {:?} > end {:?}!", start, end);
- Self { l: start, r: end }
- }
- pub fn get_start(&self) -> T {
- self.l
- }
- pub fn get_end(&self) -> T {
- self.r
- }
-}
-impl<T> IntoIterator for SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- type Item = T;
- type IntoIter = SimpleRangeIterator<T>;
- fn into_iter(self) -> Self::IntoIter {
- SimpleRangeIterator::new(self.l, self.r)
- }
-}
-/// iterator for the simple range structure
-pub struct SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- current: T,
- end: T,
-}
-impl<T> SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- pub fn new(l: T, r: T) -> Self {
- Self { current: l, end: r }
- }
-}
-impl<T> Iterator for SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- type Item = T;
- fn next(&mut self) -> Option<Self::Item> {
- if self.current == self.end {
- None
- } else {
- let t = self.current;
- self.current.step();
- Some(t)
- }
- }
-}
-/// a simple range structure for virtual page number
-pub type VPNRange = SimpleRange<VirtPageNum>;
-
-
\ No newline at end of file
+/// a simple range structure for virtual page number
+pub type VPNRange = SimpleRange<VirtPageNum>;
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/frame_allocator.rs.html b/ch5/src/os/mm/frame_allocator.rs.html
index aef8fb3d..98a2edb1 100644
--- a/ch5/src/os/mm/frame_allocator.rs.html
+++ b/ch5/src/os/mm/frame_allocator.rs.html
@@ -1,270 +1,269 @@
-frame_allocator.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-
//! Implementation of [`FrameAllocator`] which
-//! controls all the frames in the operating system.
-use super::{PhysAddr, PhysPageNum};
-use crate::config::MEMORY_END;
-use crate::sync::UPSafeCell;
-use alloc::vec::Vec;
-use core::fmt::{self, Debug, Formatter};
-use lazy_static::*;
+frame_allocator.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
//! Implementation of [`FrameAllocator`] which
+//! controls all the frames in the operating system.
+use super::{PhysAddr, PhysPageNum};
+use crate::config::MEMORY_END;
+use crate::sync::UPSafeCell;
+use alloc::vec::Vec;
+use core::fmt::{self, Debug, Formatter};
+use lazy_static::*;
-/// manage a frame which has the same lifecycle as the tracker
-pub struct FrameTracker {
- ///
- pub ppn: PhysPageNum,
+/// manage a frame which has the same lifecycle as the tracker
+pub struct FrameTracker {
+ ///
+ pub ppn: PhysPageNum,
}
-impl FrameTracker {
- ///Create an empty `FrameTracker`
- pub fn new(ppn: PhysPageNum) -> Self {
- // page cleaning
- let bytes_array = ppn.get_bytes_array();
- for i in bytes_array {
- *i = 0;
+impl FrameTracker {
+ ///Create an empty `FrameTracker`
+ pub fn new(ppn: PhysPageNum) -> Self {
+ // page cleaning
+ let bytes_array = ppn.get_bytes_array();
+ for i in bytes_array {
+ *i = 0;
}
- Self { ppn }
+ Self { ppn }
}
}
-impl Debug for FrameTracker {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("FrameTracker:PPN={:#x}", self.ppn.0))
+impl Debug for FrameTracker {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("FrameTracker:PPN={:#x}", self.ppn.0))
}
}
-impl Drop for FrameTracker {
- fn drop(&mut self) {
- frame_dealloc(self.ppn);
+impl Drop for FrameTracker {
+ fn drop(&mut self) {
+ frame_dealloc(self.ppn);
}
}
-trait FrameAllocator {
- fn new() -> Self;
- fn alloc(&mut self) -> Option<PhysPageNum>;
- fn dealloc(&mut self, ppn: PhysPageNum);
+trait FrameAllocator {
+ fn new() -> Self;
+ fn alloc(&mut self) -> Option<PhysPageNum>;
+ fn dealloc(&mut self, ppn: PhysPageNum);
}
-/// an implementation for frame allocator
-pub struct StackFrameAllocator {
- current: usize,
- end: usize,
- recycled: Vec<usize>,
+/// an implementation for frame allocator
+pub struct StackFrameAllocator {
+ current: usize,
+ end: usize,
+ recycled: Vec<usize>,
}
-impl StackFrameAllocator {
- pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
- self.current = l.0;
- self.end = r.0;
- println!("last {} Physical Frames.", self.end - self.current);
+impl StackFrameAllocator {
+ pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
+ self.current = l.0;
+ self.end = r.0;
+ println!("last {} Physical Frames.", self.end - self.current);
}
}
-impl FrameAllocator for StackFrameAllocator {
- fn new() -> Self {
- Self {
- current: 0,
- end: 0,
- recycled: Vec::new(),
+impl FrameAllocator for StackFrameAllocator {
+ fn new() -> Self {
+ Self {
+ current: 0,
+ end: 0,
+ recycled: Vec::new(),
}
}
- fn alloc(&mut self) -> Option<PhysPageNum> {
- if let Some(ppn) = self.recycled.pop() {
- Some(ppn.into())
- } else if self.current == self.end {
- None
- } else {
- self.current += 1;
- Some((self.current - 1).into())
+ fn alloc(&mut self) -> Option<PhysPageNum> {
+ if let Some(ppn) = self.recycled.pop() {
+ Some(ppn.into())
+ } else if self.current == self.end {
+ None
+ } else {
+ self.current += 1;
+ Some((self.current - 1).into())
}
}
- fn dealloc(&mut self, ppn: PhysPageNum) {
- let ppn = ppn.0;
- // validity check
- if ppn >= self.current || self.recycled.iter().any(|&v| v == ppn) {
- panic!("Frame ppn={:#x} has not been allocated!", ppn);
+ fn dealloc(&mut self, ppn: PhysPageNum) {
+ let ppn = ppn.0;
+ // validity check
+ if ppn >= self.current || self.recycled.iter().any(|&v| v == ppn) {
+ panic!("Frame ppn={:#x} has not been allocated!", ppn);
}
- // recycle
- self.recycled.push(ppn);
+ // recycle
+ self.recycled.push(ppn);
}
}
-type FrameAllocatorImpl = StackFrameAllocator;
+type FrameAllocatorImpl = StackFrameAllocator;
-lazy_static! {
- /// frame allocator instance through lazy_static!
- pub static ref FRAME_ALLOCATOR: UPSafeCell<FrameAllocatorImpl> =
- unsafe { UPSafeCell::new(FrameAllocatorImpl::new()) };
+lazy_static! {
+ /// frame allocator instance through lazy_static!
+ pub static ref FRAME_ALLOCATOR: UPSafeCell<FrameAllocatorImpl> =
+ unsafe { UPSafeCell::new(FrameAllocatorImpl::new()) };
}
-/// initiate the frame allocator using `ekernel` and `MEMORY_END`
-pub fn init_frame_allocator() {
- extern "C" {
- fn ekernel();
+/// initiate the frame allocator using `ekernel` and `MEMORY_END`
+pub fn init_frame_allocator() {
+ extern "C" {
+ fn ekernel();
}
- FRAME_ALLOCATOR.exclusive_access().init(
- PhysAddr::from(ekernel as usize).ceil(),
- PhysAddr::from(MEMORY_END).floor(),
+ FRAME_ALLOCATOR.exclusive_access().init(
+ PhysAddr::from(ekernel as usize).ceil(),
+ PhysAddr::from(MEMORY_END).floor(),
);
}
-/// allocate a frame
-pub fn frame_alloc() -> Option<FrameTracker> {
- FRAME_ALLOCATOR
- .exclusive_access()
- .alloc()
- .map(FrameTracker::new)
+/// allocate a frame
+pub fn frame_alloc() -> Option<FrameTracker> {
+ FRAME_ALLOCATOR
+ .exclusive_access()
+ .alloc()
+ .map(FrameTracker::new)
}
-/// deallocate a frame
-fn frame_dealloc(ppn: PhysPageNum) {
- FRAME_ALLOCATOR.exclusive_access().dealloc(ppn);
+/// deallocate a frame
+fn frame_dealloc(ppn: PhysPageNum) {
+ FRAME_ALLOCATOR.exclusive_access().dealloc(ppn);
}
-#[allow(unused)]
-/// a simple test for frame allocator
-pub fn frame_allocator_test() {
- let mut v: Vec<FrameTracker> = Vec::new();
- for i in 0..5 {
- let frame = frame_alloc().unwrap();
- println!("{:?}", frame);
- v.push(frame);
+#[allow(unused)]
+/// a simple test for frame allocator
+pub fn frame_allocator_test() {
+ let mut v: Vec<FrameTracker> = Vec::new();
+ for i in 0..5 {
+ let frame = frame_alloc().unwrap();
+ println!("{:?}", frame);
+ v.push(frame);
}
- v.clear();
- for i in 0..5 {
- let frame = frame_alloc().unwrap();
- println!("{:?}", frame);
- v.push(frame);
+ v.clear();
+ for i in 0..5 {
+ let frame = frame_alloc().unwrap();
+ println!("{:?}", frame);
+ v.push(frame);
}
- drop(v);
+ drop(v);
println!("frame_allocator_test passed!");
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/heap_allocator.rs.html b/ch5/src/os/mm/heap_allocator.rs.html
index 93168f2d..50696648 100644
--- a/ch5/src/os/mm/heap_allocator.rs.html
+++ b/ch5/src/os/mm/heap_allocator.rs.html
@@ -1,98 +1,97 @@
-heap_allocator.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-
//! The global allocator
-use crate::config::KERNEL_HEAP_SIZE;
-use buddy_system_allocator::LockedHeap;
+heap_allocator.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+
//! The global allocator
+use crate::config::KERNEL_HEAP_SIZE;
+use buddy_system_allocator::LockedHeap;
-#[global_allocator]
-/// heap allocator instance
-static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
+#[global_allocator]
+/// heap allocator instance
+static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
-#[alloc_error_handler]
-/// panic when heap allocation error occurs
-pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
- panic!("Heap allocation error, layout = {:?}", layout);
+#[alloc_error_handler]
+/// panic when heap allocation error occurs
+pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
+ panic!("Heap allocation error, layout = {:?}", layout);
}
-/// heap space ([u8; KERNEL_HEAP_SIZE])
-static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];
-/// initiate heap allocator
-pub fn init_heap() {
- unsafe {
- HEAP_ALLOCATOR
- .lock()
- .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE);
+/// heap space ([u8; KERNEL_HEAP_SIZE])
+static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];
+/// initiate heap allocator
+pub fn init_heap() {
+ unsafe {
+ HEAP_ALLOCATOR
+ .lock()
+ .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE);
}
}
-#[allow(unused)]
-pub fn heap_test() {
- use alloc::boxed::Box;
- use alloc::vec::Vec;
- extern "C" {
- fn sbss();
- fn ebss();
+#[allow(unused)]
+pub fn heap_test() {
+ use alloc::boxed::Box;
+ use alloc::vec::Vec;
+ extern "C" {
+ fn sbss();
+ fn ebss();
}
- let bss_range = sbss as usize..ebss as usize;
- let a = Box::new(5);
- assert_eq!(*a, 5);
- assert!(bss_range.contains(&(a.as_ref() as *const _ as usize)));
- drop(a);
- let mut v: Vec<usize> = Vec::new();
- for i in 0..500 {
- v.push(i);
+ let bss_range = sbss as usize..ebss as usize;
+ let a = Box::new(5);
+ assert_eq!(*a, 5);
+ assert!(bss_range.contains(&(a.as_ref() as *const _ as usize)));
+ drop(a);
+ let mut v: Vec<usize> = Vec::new();
+ for i in 0..500 {
+ v.push(i);
}
- for (i, val) in v.iter().take(500).enumerate() {
- assert_eq!(*val, i);
+ for (i, val) in v.iter().take(500).enumerate() {
+ assert_eq!(*val, i);
}
- assert!(bss_range.contains(&(v.as_ptr() as usize)));
- drop(v);
+ assert!(bss_range.contains(&(v.as_ptr() as usize)));
+ drop(v);
println!("heap_test passed!");
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/memory_set.rs.html b/ch5/src/os/mm/memory_set.rs.html
index d6361b90..d2da37fd 100644
--- a/ch5/src/os/mm/memory_set.rs.html
+++ b/ch5/src/os/mm/memory_set.rs.html
@@ -1,810 +1,809 @@
-memory_set.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-
//! Implementation of [`MapArea`] and [`MemorySet`].
-use super::{frame_alloc, FrameTracker};
-use super::{PTEFlags, PageTable, PageTableEntry};
-use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
-use super::{StepByOne, VPNRange};
-use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE};
-use crate::sync::UPSafeCell;
-use alloc::collections::BTreeMap;
-use alloc::sync::Arc;
-use alloc::vec::Vec;
-use core::arch::asm;
-use lazy_static::*;
-use riscv::register::satp;
+memory_set.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+
//! Implementation of [`MapArea`] and [`MemorySet`].
+use super::{frame_alloc, FrameTracker};
+use super::{PTEFlags, PageTable, PageTableEntry};
+use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
+use super::{StepByOne, VPNRange};
+use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE};
+use crate::sync::UPSafeCell;
+use alloc::collections::BTreeMap;
+use alloc::sync::Arc;
+use alloc::vec::Vec;
+use core::arch::asm;
+use lazy_static::*;
+use riscv::register::satp;
-extern "C" {
- fn stext();
- fn etext();
- fn srodata();
- fn erodata();
- fn sdata();
- fn edata();
- fn sbss_with_stack();
- fn ebss();
- fn ekernel();
- fn strampoline();
+extern "C" {
+ fn stext();
+ fn etext();
+ fn srodata();
+ fn erodata();
+ fn sdata();
+ fn edata();
+ fn sbss_with_stack();
+ fn ebss();
+ fn ekernel();
+ fn strampoline();
}
-lazy_static! {
- /// a memory set instance through lazy_static! managing kernel space
- pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> =
- Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) });
+lazy_static! {
+ /// a memory set instance through lazy_static! managing kernel space
+ pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> =
+ Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) });
}
-/// memory set structure, controls virtual-memory space
-pub struct MemorySet {
- page_table: PageTable,
- areas: Vec<MapArea>,
+/// memory set structure, controls virtual-memory space
+pub struct MemorySet {
+ page_table: PageTable,
+ areas: Vec<MapArea>,
}
-impl MemorySet {
- ///Create an empty `MemorySet`
- pub fn new_bare() -> Self {
- Self {
- page_table: PageTable::new(),
- areas: Vec::new(),
+impl MemorySet {
+ ///Create an empty `MemorySet`
+ pub fn new_bare() -> Self {
+ Self {
+ page_table: PageTable::new(),
+ areas: Vec::new(),
}
}
- ///Get pagetable `root_ppn`
- pub fn token(&self) -> usize {
- self.page_table.token()
+ ///Get pagetable `root_ppn`
+ pub fn token(&self) -> usize {
+ self.page_table.token()
}
- /// Assume that no conflicts.
- pub fn insert_framed_area(
- &mut self,
- start_va: VirtAddr,
- end_va: VirtAddr,
- permission: MapPermission,
+ /// Assume that no conflicts.
+ pub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission,
) {
- self.push(
- MapArea::new(start_va, end_va, MapType::Framed, permission),
+ self.push(
+ MapArea::new(start_va, end_va, MapType::Framed, permission),
None,
);
}
- ///Remove `MapArea` that starts with `start_vpn`
- pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) {
- if let Some((idx, area)) = self
- .areas
- .iter_mut()
- .enumerate()
- .find(|(_, area)| area.vpn_range.get_start() == start_vpn)
+ ///Remove `MapArea` that starts with `start_vpn`
+ pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) {
+ if let Some((idx, area)) = self
+ .areas
+ .iter_mut()
+ .enumerate()
+ .find(|(_, area)| area.vpn_range.get_start() == start_vpn)
{
- area.unmap(&mut self.page_table);
- self.areas.remove(idx);
+ area.unmap(&mut self.page_table);
+ self.areas.remove(idx);
}
}
- fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
- map_area.map(&mut self.page_table);
- if let Some(data) = data {
- map_area.copy_data(&mut self.page_table, data);
+ fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
+ map_area.map(&mut self.page_table);
+ if let Some(data) = data {
+ map_area.copy_data(&mut self.page_table, data);
}
- self.areas.push(map_area);
+ self.areas.push(map_area);
}
- /// Mention that trampoline is not collected by areas.
- fn map_trampoline(&mut self) {
- self.page_table.map(
- VirtAddr::from(TRAMPOLINE).into(),
- PhysAddr::from(strampoline as usize).into(),
- PTEFlags::R | PTEFlags::X,
+ /// Mention that trampoline is not collected by areas.
+ fn map_trampoline(&mut self) {
+ self.page_table.map(
+ VirtAddr::from(TRAMPOLINE).into(),
+ PhysAddr::from(strampoline as usize).into(),
+ PTEFlags::R | PTEFlags::X,
);
}
- /// Without kernel stacks.
- pub fn new_kernel() -> Self {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // map kernel sections
- println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
- println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
- println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
+ /// Without kernel stacks.
+ pub fn new_kernel() -> Self {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // map kernel sections
+ println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
+ println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
+ println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
println!(
".bss [{:#x}, {:#x})",
- sbss_with_stack as usize, ebss as usize
+ sbss_with_stack as usize, ebss as usize
);
println!("mapping .text section");
- memory_set.push(
- MapArea::new(
- (stext as usize).into(),
- (etext as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::X,
+ memory_set.push(
+ MapArea::new(
+ (stext as usize).into(),
+ (etext as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::X,
),
None,
);
println!("mapping .rodata section");
- memory_set.push(
- MapArea::new(
- (srodata as usize).into(),
- (erodata as usize).into(),
- MapType::Identical,
- MapPermission::R,
+ memory_set.push(
+ MapArea::new(
+ (srodata as usize).into(),
+ (erodata as usize).into(),
+ MapType::Identical,
+ MapPermission::R,
),
None,
);
println!("mapping .data section");
- memory_set.push(
- MapArea::new(
- (sdata as usize).into(),
- (edata as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (sdata as usize).into(),
+ (edata as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping .bss section");
- memory_set.push(
- MapArea::new(
- (sbss_with_stack as usize).into(),
- (ebss as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (sbss_with_stack as usize).into(),
+ (ebss as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping physical memory");
- memory_set.push(
- MapArea::new(
- (ekernel as usize).into(),
- MEMORY_END.into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (ekernel as usize).into(),
+ MEMORY_END.into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping memory-mapped registers");
- for pair in MMIO {
- memory_set.push(
- MapArea::new(
- (*pair).0.into(),
- ((*pair).0 + (*pair).1).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ for pair in MMIO {
+ memory_set.push(
+ MapArea::new(
+ (*pair).0.into(),
+ ((*pair).0 + (*pair).1).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
}
- memory_set
+ memory_set
}
- /// Include sections in elf and trampoline and TrapContext and user stack,
- /// also returns user_sp and entry point.
- pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // map program headers of elf, with U flag
- let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
- let elf_header = elf.header;
- let magic = elf_header.pt1.magic;
- assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
- let ph_count = elf_header.pt2.ph_count();
- let mut max_end_vpn = VirtPageNum(0);
- for i in 0..ph_count {
- let ph = elf.program_header(i).unwrap();
- if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
- let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
- let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
- let mut map_perm = MapPermission::U;
- let ph_flags = ph.flags();
- if ph_flags.is_read() {
- map_perm |= MapPermission::R;
+ /// Include sections in elf and trampoline and TrapContext and user stack,
+ /// also returns user_sp and entry point.
+ pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // map program headers of elf, with U flag
+ let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
+ let elf_header = elf.header;
+ let magic = elf_header.pt1.magic;
+ assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
+ let ph_count = elf_header.pt2.ph_count();
+ let mut max_end_vpn = VirtPageNum(0);
+ for i in 0..ph_count {
+ let ph = elf.program_header(i).unwrap();
+ if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
+ let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
+ let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
+ let mut map_perm = MapPermission::U;
+ let ph_flags = ph.flags();
+ if ph_flags.is_read() {
+ map_perm |= MapPermission::R;
}
- if ph_flags.is_write() {
- map_perm |= MapPermission::W;
+ if ph_flags.is_write() {
+ map_perm |= MapPermission::W;
}
- if ph_flags.is_execute() {
- map_perm |= MapPermission::X;
+ if ph_flags.is_execute() {
+ map_perm |= MapPermission::X;
}
- let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm);
- max_end_vpn = map_area.vpn_range.get_end();
- memory_set.push(
- map_area,
- Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]),
+ let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm);
+ max_end_vpn = map_area.vpn_range.get_end();
+ memory_set.push(
+ map_area,
+ Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]),
);
}
}
- // map user stack with U flags
- let max_end_va: VirtAddr = max_end_vpn.into();
- let mut user_stack_bottom: usize = max_end_va.into();
- // guard page
- user_stack_bottom += PAGE_SIZE;
- let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
- memory_set.push(
- MapArea::new(
- user_stack_bottom.into(),
- user_stack_top.into(),
- MapType::Framed,
- MapPermission::R | MapPermission::W | MapPermission::U,
+ // map user stack with U flags
+ let max_end_va: VirtAddr = max_end_vpn.into();
+ let mut user_stack_bottom: usize = max_end_va.into();
+ // guard page
+ user_stack_bottom += PAGE_SIZE;
+ let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
+ memory_set.push(
+ MapArea::new(
+ user_stack_bottom.into(),
+ user_stack_top.into(),
+ MapType::Framed,
+ MapPermission::R | MapPermission::W | MapPermission::U,
),
None,
);
- // map TrapContext
- memory_set.push(
- MapArea::new(
- TRAP_CONTEXT.into(),
- TRAMPOLINE.into(),
- MapType::Framed,
- MapPermission::R | MapPermission::W,
+ // map TrapContext
+ memory_set.push(
+ MapArea::new(
+ TRAP_CONTEXT.into(),
+ TRAMPOLINE.into(),
+ MapType::Framed,
+ MapPermission::R | MapPermission::W,
),
None,
);
(
- memory_set,
- user_stack_top,
- elf.header.pt2.entry_point() as usize,
+ memory_set,
+ user_stack_top,
+ elf.header.pt2.entry_point() as usize,
)
}
- ///Clone a same `MemorySet`
- pub fn from_existed_user(user_space: &Self) -> Self {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // copy data sections/trap_context/user_stack
- for area in user_space.areas.iter() {
- let new_area = MapArea::from_another(area);
- memory_set.push(new_area, None);
- // copy data from another space
- for vpn in area.vpn_range {
- let src_ppn = user_space.translate(vpn).unwrap().ppn();
- let dst_ppn = memory_set.translate(vpn).unwrap().ppn();
- dst_ppn
- .get_bytes_array()
- .copy_from_slice(src_ppn.get_bytes_array());
+ ///Clone a same `MemorySet`
+ pub fn from_existed_user(user_space: &Self) -> Self {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // copy data sections/trap_context/user_stack
+ for area in user_space.areas.iter() {
+ let new_area = MapArea::from_another(area);
+ memory_set.push(new_area, None);
+ // copy data from another space
+ for vpn in area.vpn_range {
+ let src_ppn = user_space.translate(vpn).unwrap().ppn();
+ let dst_ppn = memory_set.translate(vpn).unwrap().ppn();
+ dst_ppn
+ .get_bytes_array()
+ .copy_from_slice(src_ppn.get_bytes_array());
}
}
- memory_set
+ memory_set
}
- ///Refresh TLB with `sfence.vma`
- pub fn activate(&self) {
- let satp = self.page_table.token();
- unsafe {
- satp::write(satp);
+ ///Refresh TLB with `sfence.vma`
+ pub fn activate(&self) {
+ let satp = self.page_table.token();
+ unsafe {
+ satp::write(satp);
asm!("sfence.vma");
}
}
- ///Translate throuth pagetable
- pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
- self.page_table.translate(vpn)
+ ///Translate throuth pagetable
+ pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
+ self.page_table.translate(vpn)
}
- ///Remove all `MapArea`
- pub fn recycle_data_pages(&mut self) {
- //*self = Self::new_bare();
- self.areas.clear();
+ ///Remove all `MapArea`
+ pub fn recycle_data_pages(&mut self) {
+ //*self = Self::new_bare();
+ self.areas.clear();
}
}
-/// map area structure, controls a contiguous piece of virtual memory
-pub struct MapArea {
- vpn_range: VPNRange,
- data_frames: BTreeMap<VirtPageNum, FrameTracker>,
- map_type: MapType,
- map_perm: MapPermission,
+/// map area structure, controls a contiguous piece of virtual memory
+pub struct MapArea {
+ vpn_range: VPNRange,
+ data_frames: BTreeMap<VirtPageNum, FrameTracker>,
+ map_type: MapType,
+ map_perm: MapPermission,
}
-impl MapArea {
- pub fn new(
- start_va: VirtAddr,
- end_va: VirtAddr,
- map_type: MapType,
- map_perm: MapPermission,
- ) -> Self {
- let start_vpn: VirtPageNum = start_va.floor();
- let end_vpn: VirtPageNum = end_va.ceil();
- Self {
- vpn_range: VPNRange::new(start_vpn, end_vpn),
- data_frames: BTreeMap::new(),
- map_type,
- map_perm,
+impl MapArea {
+ pub fn new(
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ map_type: MapType,
+ map_perm: MapPermission,
+ ) -> Self {
+ let start_vpn: VirtPageNum = start_va.floor();
+ let end_vpn: VirtPageNum = end_va.ceil();
+ Self {
+ vpn_range: VPNRange::new(start_vpn, end_vpn),
+ data_frames: BTreeMap::new(),
+ map_type,
+ map_perm,
}
}
- pub fn from_another(another: &Self) -> Self {
- Self {
- vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()),
- data_frames: BTreeMap::new(),
- map_type: another.map_type,
- map_perm: another.map_perm,
+ pub fn from_another(another: &Self) -> Self {
+ Self {
+ vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()),
+ data_frames: BTreeMap::new(),
+ map_type: another.map_type,
+ map_perm: another.map_perm,
}
}
- pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
- let ppn: PhysPageNum;
- match self.map_type {
- MapType::Identical => {
- ppn = PhysPageNum(vpn.0);
+ pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
+ let ppn: PhysPageNum;
+ match self.map_type {
+ MapType::Identical => {
+ ppn = PhysPageNum(vpn.0);
}
- MapType::Framed => {
- let frame = frame_alloc().unwrap();
- ppn = frame.ppn;
- self.data_frames.insert(vpn, frame);
+ MapType::Framed => {
+ let frame = frame_alloc().unwrap();
+ ppn = frame.ppn;
+ self.data_frames.insert(vpn, frame);
}
}
- let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
- page_table.map(vpn, ppn, pte_flags);
+ let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
+ page_table.map(vpn, ppn, pte_flags);
}
- pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
- if self.map_type == MapType::Framed {
- self.data_frames.remove(&vpn);
+ pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
+ if self.map_type == MapType::Framed {
+ self.data_frames.remove(&vpn);
}
- page_table.unmap(vpn);
+ page_table.unmap(vpn);
}
- pub fn map(&mut self, page_table: &mut PageTable) {
- for vpn in self.vpn_range {
- self.map_one(page_table, vpn);
+ pub fn map(&mut self, page_table: &mut PageTable) {
+ for vpn in self.vpn_range {
+ self.map_one(page_table, vpn);
}
}
- pub fn unmap(&mut self, page_table: &mut PageTable) {
- for vpn in self.vpn_range {
- self.unmap_one(page_table, vpn);
+ pub fn unmap(&mut self, page_table: &mut PageTable) {
+ for vpn in self.vpn_range {
+ self.unmap_one(page_table, vpn);
}
}
- /// data: start-aligned but maybe with shorter length
- /// assume that all frames were cleared before
- pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
- assert_eq!(self.map_type, MapType::Framed);
- let mut start: usize = 0;
- let mut current_vpn = self.vpn_range.get_start();
- let len = data.len();
- loop {
- let src = &data[start..len.min(start + PAGE_SIZE)];
- let dst = &mut page_table
- .translate(current_vpn)
- .unwrap()
- .ppn()
- .get_bytes_array()[..src.len()];
- dst.copy_from_slice(src);
- start += PAGE_SIZE;
- if start >= len {
+ /// data: start-aligned but maybe with shorter length
+ /// assume that all frames were cleared before
+ pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
+ assert_eq!(self.map_type, MapType::Framed);
+ let mut start: usize = 0;
+ let mut current_vpn = self.vpn_range.get_start();
+ let len = data.len();
+ loop {
+ let src = &data[start..len.min(start + PAGE_SIZE)];
+ let dst = &mut page_table
+ .translate(current_vpn)
+ .unwrap()
+ .ppn()
+ .get_bytes_array()[..src.len()];
+ dst.copy_from_slice(src);
+ start += PAGE_SIZE;
+ if start >= len {
break;
}
- current_vpn.step();
+ current_vpn.step();
}
}
}
-#[derive(Copy, Clone, PartialEq, Debug)]
-/// map type for memory set: identical or framed
-pub enum MapType {
- Identical,
- Framed,
+#[derive(Copy, Clone, PartialEq, Debug)]
+/// map type for memory set: identical or framed
+pub enum MapType {
+ Identical,
+ Framed,
}
-bitflags! {
- /// map permission corresponding to that in pte: `R W X U`
- pub struct MapPermission: u8 {
- ///Readable
- const R = 1 << 1;
- ///Writable
- const W = 1 << 2;
- ///Excutable
- const X = 1 << 3;
- ///Accessible in U mode
- const U = 1 << 4;
+bitflags! {
+ /// map permission corresponding to that in pte: `R W X U`
+ pub struct MapPermission: u8 {
+ ///Readable
+ const R = 1 << 1;
+ ///Writable
+ const W = 1 << 2;
+ ///Excutable
+ const X = 1 << 3;
+ ///Accessible in U mode
+ const U = 1 << 4;
}
}
-#[allow(unused)]
-///Check PageTable running correctly
-pub fn remap_test() {
- let mut kernel_space = KERNEL_SPACE.exclusive_access();
- let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into();
- let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into();
- let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into();
- assert!(!kernel_space
- .page_table
- .translate(mid_text.floor())
- .unwrap()
- .writable(),);
- assert!(!kernel_space
- .page_table
- .translate(mid_rodata.floor())
- .unwrap()
- .writable(),);
- assert!(!kernel_space
- .page_table
- .translate(mid_data.floor())
- .unwrap()
- .executable(),);
+#[allow(unused)]
+///Check PageTable running correctly
+pub fn remap_test() {
+ let mut kernel_space = KERNEL_SPACE.exclusive_access();
+ let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into();
+ let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into();
+ let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into();
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_text.floor())
+ .unwrap()
+ .writable(),);
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_rodata.floor())
+ .unwrap()
+ .writable(),);
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_data.floor())
+ .unwrap()
+ .executable(),);
println!("remap_test passed!");
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/mod.rs.html b/ch5/src/os/mm/mod.rs.html
index 6aac7a37..952076a9 100644
--- a/ch5/src/os/mm/mod.rs.html
+++ b/ch5/src/os/mm/mod.rs.html
@@ -1,54 +1,53 @@
-mod.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-
//! Memory management implementation
-//!
-//! SV39 page-based virtual-memory architecture for RV64 systems, and
-//! everything about memory management, like frame allocator, page table,
-//! map area and memory set, is implemented here.
-//!
-//! Every task or process has a memory_set to control its virtual memory.
-mod address;
-mod frame_allocator;
-mod heap_allocator;
-mod memory_set;
-mod page_table;
+mod.rs - source //! Memory management implementation
+//!
+//! SV39 page-based virtual-memory architecture for RV64 systems, and
+//! everything about memory management, like frame allocator, page table,
+//! map area and memory set, is implemented here.
+//!
+//! Every task or process has a memory_set to control its virtual memory.
+mod address;
+mod frame_allocator;
+mod heap_allocator;
+mod memory_set;
+mod page_table;
-pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
-use address::{StepByOne, VPNRange};
-pub use frame_allocator::{frame_alloc, FrameTracker};
-pub use memory_set::remap_test;
-pub use memory_set::{MapPermission, MemorySet, KERNEL_SPACE};
-pub use page_table::{translated_byte_buffer, translated_refmut, translated_str, PageTableEntry};
-use page_table::{PTEFlags, PageTable};
-/// initiate heap allocator, frame allocator and kernel space
-pub fn init() {
- heap_allocator::init_heap();
- frame_allocator::init_frame_allocator();
- KERNEL_SPACE.exclusive_access().activate();
+pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
+use address::{StepByOne, VPNRange};
+pub use frame_allocator::{frame_alloc, FrameTracker};
+pub use memory_set::remap_test;
+pub use memory_set::{MapPermission, MemorySet, KERNEL_SPACE};
+pub use page_table::{translated_byte_buffer, translated_refmut, translated_str, PageTableEntry};
+use page_table::{PTEFlags, PageTable};
+/// initiate heap allocator, frame allocator and kernel space
+pub fn init() {
+ heap_allocator::init_heap();
+ frame_allocator::init_frame_allocator();
+ KERNEL_SPACE.exclusive_access().activate();
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/mm/page_table.rs.html b/ch5/src/os/mm/page_table.rs.html
index a4a3a08f..11973522 100644
--- a/ch5/src/os/mm/page_table.rs.html
+++ b/ch5/src/os/mm/page_table.rs.html
@@ -1,408 +1,407 @@
-page_table.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-
//! Implementation of [`PageTableEntry`] and [`PageTable`].
-use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
-use alloc::string::String;
-use alloc::vec;
-use alloc::vec::Vec;
-use bitflags::*;
+page_table.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+
//! Implementation of [`PageTableEntry`] and [`PageTable`].
+use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
+use alloc::string::String;
+use alloc::vec;
+use alloc::vec::Vec;
+use bitflags::*;
-bitflags! {
- pub struct PTEFlags: u8 {
- const V = 1 << 0;
- const R = 1 << 1;
- const W = 1 << 2;
- const X = 1 << 3;
- const U = 1 << 4;
- const G = 1 << 5;
- const A = 1 << 6;
- const D = 1 << 7;
+bitflags! {
+ pub struct PTEFlags: u8 {
+ const V = 1 << 0;
+ const R = 1 << 1;
+ const W = 1 << 2;
+ const X = 1 << 3;
+ const U = 1 << 4;
+ const G = 1 << 5;
+ const A = 1 << 6;
+ const D = 1 << 7;
}
}
-#[derive(Copy, Clone)]
-#[repr(C)]
-/// page table entry structure
-pub struct PageTableEntry {
- ///PTE
- pub bits: usize,
+#[derive(Copy, Clone)]
+#[repr(C)]
+/// page table entry structure
+pub struct PageTableEntry {
+ ///PTE
+ pub bits: usize,
}
-impl PageTableEntry {
- ///Create a PTE from ppn
- pub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self {
- PageTableEntry {
- bits: ppn.0 << 10 | flags.bits as usize,
+impl PageTableEntry {
+ ///Create a PTE from ppn
+ pub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self {
+ PageTableEntry {
+ bits: ppn.0 << 10 | flags.bits as usize,
}
}
- ///Return an empty PTE
- pub fn empty() -> Self {
- PageTableEntry { bits: 0 }
+ ///Return an empty PTE
+ pub fn empty() -> Self {
+ PageTableEntry { bits: 0 }
}
- ///Return 44bit ppn
- pub fn ppn(&self) -> PhysPageNum {
- (self.bits >> 10 & ((1usize << 44) - 1)).into()
+ ///Return 44bit ppn
+ pub fn ppn(&self) -> PhysPageNum {
+ (self.bits >> 10 & ((1usize << 44) - 1)).into()
}
- ///Return 10bit flag
- pub fn flags(&self) -> PTEFlags {
- PTEFlags::from_bits(self.bits as u8).unwrap()
+ ///Return 10bit flag
+ pub fn flags(&self) -> PTEFlags {
+ PTEFlags::from_bits(self.bits as u8).unwrap()
}
- ///Check PTE valid
- pub fn is_valid(&self) -> bool {
- (self.flags() & PTEFlags::V) != PTEFlags::empty()
+ ///Check PTE valid
+ pub fn is_valid(&self) -> bool {
+ (self.flags() & PTEFlags::V) != PTEFlags::empty()
}
- ///Check PTE readable
- pub fn readable(&self) -> bool {
- (self.flags() & PTEFlags::R) != PTEFlags::empty()
+ ///Check PTE readable
+ pub fn readable(&self) -> bool {
+ (self.flags() & PTEFlags::R) != PTEFlags::empty()
}
- ///Check PTE writable
- pub fn writable(&self) -> bool {
- (self.flags() & PTEFlags::W) != PTEFlags::empty()
+ ///Check PTE writable
+ pub fn writable(&self) -> bool {
+ (self.flags() & PTEFlags::W) != PTEFlags::empty()
}
- ///Check PTE executable
- pub fn executable(&self) -> bool {
- (self.flags() & PTEFlags::X) != PTEFlags::empty()
+ ///Check PTE executable
+ pub fn executable(&self) -> bool {
+ (self.flags() & PTEFlags::X) != PTEFlags::empty()
}
}
-pub struct PageTable {
- root_ppn: PhysPageNum,
- frames: Vec<FrameTracker>,
+pub struct PageTable {
+ root_ppn: PhysPageNum,
+ frames: Vec<FrameTracker>,
}
-/// Assume that it won't oom when creating/mapping.
-impl PageTable {
- pub fn new() -> Self {
- let frame = frame_alloc().unwrap();
- PageTable {
- root_ppn: frame.ppn,
- frames: vec![frame],
+/// Assume that it won't oom when creating/mapping.
+impl PageTable {
+ pub fn new() -> Self {
+ let frame = frame_alloc().unwrap();
+ PageTable {
+ root_ppn: frame.ppn,
+ frames: vec![frame],
}
}
- /// Temporarily used to get arguments from user space.
- pub fn from_token(satp: usize) -> Self {
- Self {
- root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
- frames: Vec::new(),
+ /// Temporarily used to get arguments from user space.
+ pub fn from_token(satp: usize) -> Self {
+ Self {
+ root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
+ frames: Vec::new(),
}
}
- fn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
- let idxs = vpn.indexes();
- let mut ppn = self.root_ppn;
- let mut result: Option<&mut PageTableEntry> = None;
- for (i, idx) in idxs.iter().enumerate() {
- let pte = &mut ppn.get_pte_array()[*idx];
- if i == 2 {
- result = Some(pte);
+ fn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
+ let idxs = vpn.indexes();
+ let mut ppn = self.root_ppn;
+ let mut result: Option<&mut PageTableEntry> = None;
+ for (i, idx) in idxs.iter().enumerate() {
+ let pte = &mut ppn.get_pte_array()[*idx];
+ if i == 2 {
+ result = Some(pte);
break;
}
- if !pte.is_valid() {
- let frame = frame_alloc().unwrap();
- *pte = PageTableEntry::new(frame.ppn, PTEFlags::V);
- self.frames.push(frame);
+ if !pte.is_valid() {
+ let frame = frame_alloc().unwrap();
+ *pte = PageTableEntry::new(frame.ppn, PTEFlags::V);
+ self.frames.push(frame);
}
- ppn = pte.ppn();
+ ppn = pte.ppn();
}
- result
+ result
}
- fn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
- let idxs = vpn.indexes();
- let mut ppn = self.root_ppn;
- let mut result: Option<&mut PageTableEntry> = None;
- for (i, idx) in idxs.iter().enumerate() {
- let pte = &mut ppn.get_pte_array()[*idx];
- if i == 2 {
- result = Some(pte);
+ fn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
+ let idxs = vpn.indexes();
+ let mut ppn = self.root_ppn;
+ let mut result: Option<&mut PageTableEntry> = None;
+ for (i, idx) in idxs.iter().enumerate() {
+ let pte = &mut ppn.get_pte_array()[*idx];
+ if i == 2 {
+ result = Some(pte);
break;
}
- if !pte.is_valid() {
- return None;
+ if !pte.is_valid() {
+ return None;
}
- ppn = pte.ppn();
+ ppn = pte.ppn();
}
- result
+ result
}
- #[allow(unused)]
- pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
- let pte = self.find_pte_create(vpn).unwrap();
- assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
- *pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
+ #[allow(unused)]
+ pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
+ let pte = self.find_pte_create(vpn).unwrap();
+ assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
+ *pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
}
- #[allow(unused)]
- pub fn unmap(&mut self, vpn: VirtPageNum) {
- let pte = self.find_pte(vpn).unwrap();
- assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn);
- *pte = PageTableEntry::empty();
+ #[allow(unused)]
+ pub fn unmap(&mut self, vpn: VirtPageNum) {
+ let pte = self.find_pte(vpn).unwrap();
+ assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn);
+ *pte = PageTableEntry::empty();
}
- pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
- self.find_pte(vpn).map(|pte| *pte)
+ pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
+ self.find_pte(vpn).map(|pte| *pte)
}
- pub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr> {
- self.find_pte(va.clone().floor()).map(|pte| {
- //println!("translate_va:va = {:?}", va);
- let aligned_pa: PhysAddr = pte.ppn().into();
- //println!("translate_va:pa_align = {:?}", aligned_pa);
- let offset = va.page_offset();
- let aligned_pa_usize: usize = aligned_pa.into();
- (aligned_pa_usize + offset).into()
+ pub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr> {
+ self.find_pte(va.clone().floor()).map(|pte| {
+ //println!("translate_va:va = {:?}", va);
+ let aligned_pa: PhysAddr = pte.ppn().into();
+ //println!("translate_va:pa_align = {:?}", aligned_pa);
+ let offset = va.page_offset();
+ let aligned_pa_usize: usize = aligned_pa.into();
+ (aligned_pa_usize + offset).into()
})
}
- pub fn token(&self) -> usize {
- 8usize << 60 | self.root_ppn.0
- }
+ pub fn token(&self) -> usize {
+ 8usize << 60 | self.root_ppn.0
+ }
}
-/// translate a pointer to a mutable u8 Vec through page table
-pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static mut [u8]> {
- let page_table = PageTable::from_token(token);
- let mut start = ptr as usize;
- let end = start + len;
- let mut v = Vec::new();
- while start < end {
- let start_va = VirtAddr::from(start);
- let mut vpn = start_va.floor();
- let ppn = page_table.translate(vpn).unwrap().ppn();
- vpn.step();
- let mut end_va: VirtAddr = vpn.into();
- end_va = end_va.min(VirtAddr::from(end));
- if end_va.page_offset() == 0 {
- v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..]);
- } else {
- v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
+/// translate a pointer to a mutable u8 Vec through page table
+pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static mut [u8]> {
+ let page_table = PageTable::from_token(token);
+ let mut start = ptr as usize;
+ let end = start + len;
+ let mut v = Vec::new();
+ while start < end {
+ let start_va = VirtAddr::from(start);
+ let mut vpn = start_va.floor();
+ let ppn = page_table.translate(vpn).unwrap().ppn();
+ vpn.step();
+ let mut end_va: VirtAddr = vpn.into();
+ end_va = end_va.min(VirtAddr::from(end));
+ if end_va.page_offset() == 0 {
+ v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..]);
+ } else {
+ v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
}
- start = end_va.into();
+ start = end_va.into();
}
- v
+ v
}
-/// translate a pointer to a mutable u8 Vec end with `\0` through page table to a `String`
-pub fn translated_str(token: usize, ptr: *const u8) -> String {
- let page_table = PageTable::from_token(token);
- let mut string = String::new();
- let mut va = ptr as usize;
- loop {
- let ch: u8 = *(page_table
- .translate_va(VirtAddr::from(va))
- .unwrap()
- .get_mut());
- if ch == 0 {
+/// translate a pointer to a mutable u8 Vec end with `\0` through page table to a `String`
+pub fn translated_str(token: usize, ptr: *const u8) -> String {
+ let page_table = PageTable::from_token(token);
+ let mut string = String::new();
+ let mut va = ptr as usize;
+ loop {
+ let ch: u8 = *(page_table
+ .translate_va(VirtAddr::from(va))
+ .unwrap()
+ .get_mut());
+ if ch == 0 {
break;
- } else {
- string.push(ch as char);
- va += 1;
+ } else {
+ string.push(ch as char);
+ va += 1;
}
}
- string
+ string
}
-///translate a generic through page table and return a mutable reference
-pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T {
- //println!("into translated_refmut!");
- let page_table = PageTable::from_token(token);
- let va = ptr as usize;
- //println!("translated_refmut: before translate_va");
- page_table
- .translate_va(VirtAddr::from(va))
- .unwrap()
- .get_mut()
+///translate a generic through page table and return a mutable reference
+pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T {
+ //println!("into translated_refmut!");
+ let page_table = PageTable::from_token(token);
+ let va = ptr as usize;
+ //println!("translated_refmut: before translate_va");
+ page_table
+ .translate_va(VirtAddr::from(va))
+ .unwrap()
+ .get_mut()
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/sbi.rs.html b/ch5/src/os/sbi.rs.html
index 1799d7f8..ca251be2 100644
--- a/ch5/src/os/sbi.rs.html
+++ b/ch5/src/os/sbi.rs.html
@@ -1,62 +1,61 @@
-sbi.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-
//! SBI call wrappers
-#![allow(unused)]
+sbi.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
//! SBI call wrappers
+#![allow(unused)]
-/// use sbi call to putchar in console (qemu uart handler)
-pub fn console_putchar(c: usize) {
- #[allow(deprecated)]
- sbi_rt::legacy::console_putchar(c);
+/// use sbi call to putchar in console (qemu uart handler)
+pub fn console_putchar(c: usize) {
+ #[allow(deprecated)]
+ sbi_rt::legacy::console_putchar(c);
}
-/// use sbi call to getchar from console (qemu uart handler)
-pub fn console_getchar() -> usize {
- #[allow(deprecated)]
- sbi_rt::legacy::console_getchar()
+/// use sbi call to getchar from console (qemu uart handler)
+pub fn console_getchar() -> usize {
+ #[allow(deprecated)]
+ sbi_rt::legacy::console_getchar()
}
-/// use sbi call to set timer
-pub fn set_timer(timer: usize) {
- sbi_rt::set_timer(timer as _);
+/// use sbi call to set timer
+pub fn set_timer(timer: usize) {
+ sbi_rt::set_timer(timer as _);
}
-/// use sbi call to shutdown the kernel
-pub fn shutdown(failure: bool) -> ! {
- use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure};
- if !failure {
- system_reset(Shutdown, NoReason);
- } else {
- system_reset(Shutdown, SystemFailure);
+/// use sbi call to shutdown the kernel
+pub fn shutdown(failure: bool) -> ! {
+ use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure};
+ if !failure {
+ system_reset(Shutdown, NoReason);
+ } else {
+ system_reset(Shutdown, SystemFailure);
}
unreachable!()
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/sync/mod.rs.html b/ch5/src/os/sync/mod.rs.html
index 1833b02b..89ed0bf7 100644
--- a/ch5/src/os/sync/mod.rs.html
+++ b/ch5/src/os/sync/mod.rs.html
@@ -1,10 +1,9 @@
-mod.rs - source
\ No newline at end of file
diff --git a/ch5/src/os/sync/up.rs.html b/ch5/src/os/sync/up.rs.html
index 66ccab8d..e20054e7 100644
--- a/ch5/src/os/sync/up.rs.html
+++ b/ch5/src/os/sync/up.rs.html
@@ -1,62 +1,61 @@
-up.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-
//! Uniprocessor interior mutability primitives
-use core::cell::{RefCell, RefMut};
+up.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
//! Uniprocessor interior mutability primitives
+use core::cell::{RefCell, RefMut};
-/// Wrap a static data structure inside it so that we are
-/// able to access it without any `unsafe`.
-///
-/// We should only use it in uniprocessor.
-///
-/// In order to get mutable reference of inner data, call
-/// `exclusive_access`.
-pub struct UPSafeCell<T> {
- /// inner data
- inner: RefCell<T>,
+/// Wrap a static data structure inside it so that we are
+/// able to access it without any `unsafe`.
+///
+/// We should only use it in uniprocessor.
+///
+/// In order to get mutable reference of inner data, call
+/// `exclusive_access`.
+pub struct UPSafeCell<T> {
+ /// inner data
+ inner: RefCell<T>,
}
-unsafe impl<T> Sync for UPSafeCell<T> {}
+unsafe impl<T> Sync for UPSafeCell<T> {}
-impl<T> UPSafeCell<T> {
- /// User is responsible to guarantee that inner struct is only used in
- /// uniprocessor.
- pub unsafe fn new(value: T) -> Self {
- Self {
- inner: RefCell::new(value),
+impl<T> UPSafeCell<T> {
+ /// User is responsible to guarantee that inner struct is only used in
+ /// uniprocessor.
+ pub unsafe fn new(value: T) -> Self {
+ Self {
+ inner: RefCell::new(value),
}
}
- /// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
- pub fn exclusive_access(&self) -> RefMut<'_, T> {
- self.inner.borrow_mut()
+ /// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+ pub fn exclusive_access(&self) -> RefMut<'_, T> {
+ self.inner.borrow_mut()
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/syscall/fs.rs.html b/ch5/src/os/syscall/fs.rs.html
index 202d4d95..ca7ddf0a 100644
--- a/ch5/src/os/syscall/fs.rs.html
+++ b/ch5/src/os/syscall/fs.rs.html
@@ -1,100 +1,99 @@
-fs.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-
//! File and filesystem-related syscalls
-use crate::mm::translated_byte_buffer;
-use crate::sbi::console_getchar;
-use crate::task::{current_user_token, suspend_current_and_run_next};
+fs.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
//! File and filesystem-related syscalls
+use crate::mm::translated_byte_buffer;
+use crate::sbi::console_getchar;
+use crate::task::{current_user_token, suspend_current_and_run_next};
-const FD_STDIN: usize = 0;
-const FD_STDOUT: usize = 1;
+const FD_STDIN: usize = 0;
+const FD_STDOUT: usize = 1;
-pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
- match fd {
- FD_STDOUT => {
- let buffers = translated_byte_buffer(current_user_token(), buf, len);
- for buffer in buffers {
- print!("{}", core::str::from_utf8(buffer).unwrap());
+pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
+ match fd {
+ FD_STDOUT => {
+ let buffers = translated_byte_buffer(current_user_token(), buf, len);
+ for buffer in buffers {
+ print!("{}", core::str::from_utf8(buffer).unwrap());
}
- len as isize
+ len as isize
}
- _ => {
+ _ => {
panic!("Unsupported fd in sys_write!");
}
}
}
-pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
- match fd {
- FD_STDIN => {
- assert_eq!(len, 1, "Only support len = 1 in sys_read!");
- let mut c: usize;
- loop {
- c = console_getchar();
- if c == 0 {
- suspend_current_and_run_next();
+pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
+ match fd {
+ FD_STDIN => {
+ assert_eq!(len, 1, "Only support len = 1 in sys_read!");
+ let mut c: usize;
+ loop {
+ c = console_getchar();
+ if c == 0 {
+ suspend_current_and_run_next();
continue;
- } else {
+ } else {
break;
}
}
- let ch = c as u8;
- let mut buffers = translated_byte_buffer(current_user_token(), buf, len);
- unsafe {
- buffers[0].as_mut_ptr().write_volatile(ch);
+ let ch = c as u8;
+ let mut buffers = translated_byte_buffer(current_user_token(), buf, len);
+ unsafe {
+ buffers[0].as_mut_ptr().write_volatile(ch);
}
- 1
- }
- _ => {
+ 1
+ }
+ _ => {
panic!("Unsupported fd in sys_read!");
}
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/syscall/mod.rs.html b/ch5/src/os/syscall/mod.rs.html
index 8db5ced3..926d879e 100644
--- a/ch5/src/os/syscall/mod.rs.html
+++ b/ch5/src/os/syscall/mod.rs.html
@@ -1,84 +1,83 @@
-mod.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-
//! Implementation of syscalls
-//!
-//! The single entry point to all system calls, [`syscall()`], is called
-//! whenever userspace wishes to perform a system call using the `ecall`
-//! instruction. In this case, the processor raises an 'Environment call from
-//! U-mode' exception, which is handled as one of the cases in
-//! [`crate::trap::trap_handler`].
-//!
-//! For clarity, each single syscall is implemented as its own function, named
-//! `sys_` then the name of the syscall. You can find functions like this in
-//! submodules, and you should also implement syscalls this way.
-const SYSCALL_READ: usize = 63;
-const SYSCALL_WRITE: usize = 64;
-const SYSCALL_EXIT: usize = 93;
-const SYSCALL_YIELD: usize = 124;
-const SYSCALL_GET_TIME: usize = 169;
-const SYSCALL_GETPID: usize = 172;
-const SYSCALL_FORK: usize = 220;
-const SYSCALL_EXEC: usize = 221;
-const SYSCALL_WAITPID: usize = 260;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
//! Implementation of syscalls
+//!
+//! The single entry point to all system calls, [`syscall()`], is called
+//! whenever userspace wishes to perform a system call using the `ecall`
+//! instruction. In this case, the processor raises an 'Environment call from
+//! U-mode' exception, which is handled as one of the cases in
+//! [`crate::trap::trap_handler`].
+//!
+//! For clarity, each single syscall is implemented as its own function, named
+//! `sys_` then the name of the syscall. You can find functions like this in
+//! submodules, and you should also implement syscalls this way.
+const SYSCALL_READ: usize = 63;
+const SYSCALL_WRITE: usize = 64;
+const SYSCALL_EXIT: usize = 93;
+const SYSCALL_YIELD: usize = 124;
+const SYSCALL_GET_TIME: usize = 169;
+const SYSCALL_GETPID: usize = 172;
+const SYSCALL_FORK: usize = 220;
+const SYSCALL_EXEC: usize = 221;
+const SYSCALL_WAITPID: usize = 260;
-mod fs;
-mod process;
+mod fs;
+mod process;
-use fs::*;
-use process::*;
-/// handle syscall exception with `syscall_id` and other arguments
-pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
- match syscall_id {
- SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
- SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
- SYSCALL_EXIT => sys_exit(args[0] as i32),
- SYSCALL_YIELD => sys_yield(),
- SYSCALL_GET_TIME => sys_get_time(),
- SYSCALL_GETPID => sys_getpid(),
- SYSCALL_FORK => sys_fork(),
- SYSCALL_EXEC => sys_exec(args[0] as *const u8),
- SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
- _ => panic!("Unsupported syscall_id: {}", syscall_id),
+use fs::*;
+use process::*;
+/// handle syscall exception with `syscall_id` and other arguments
+pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
+ match syscall_id {
+ SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
+ SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
+ SYSCALL_EXIT => sys_exit(args[0] as i32),
+ SYSCALL_YIELD => sys_yield(),
+ SYSCALL_GET_TIME => sys_get_time(),
+ SYSCALL_GETPID => sys_getpid(),
+ SYSCALL_FORK => sys_fork(),
+ SYSCALL_EXEC => sys_exec(args[0] as *const u8),
+ SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
+ _ => panic!("Unsupported syscall_id: {}", syscall_id),
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/syscall/process.rs.html b/ch5/src/os/syscall/process.rs.html
index 5c0a25f6..6b9d51da 100644
--- a/ch5/src/os/syscall/process.rs.html
+++ b/ch5/src/os/syscall/process.rs.html
@@ -1,180 +1,179 @@
-process.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-
use crate::loader::get_app_data_by_name;
-use crate::mm::{translated_refmut, translated_str};
-use crate::task::{
- add_task, current_task, current_user_token, exit_current_and_run_next,
- suspend_current_and_run_next,
+process.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+
use crate::loader::get_app_data_by_name;
+use crate::mm::{translated_refmut, translated_str};
+use crate::task::{
+ add_task, current_task, current_user_token, exit_current_and_run_next,
+ suspend_current_and_run_next,
};
-use crate::timer::get_time_ms;
-use alloc::sync::Arc;
+use crate::timer::get_time_ms;
+use alloc::sync::Arc;
-pub fn sys_exit(exit_code: i32) -> ! {
- exit_current_and_run_next(exit_code);
+pub fn sys_exit(exit_code: i32) -> ! {
+ exit_current_and_run_next(exit_code);
panic!("Unreachable in sys_exit!");
}
-pub fn sys_yield() -> isize {
- suspend_current_and_run_next();
- 0
+pub fn sys_yield() -> isize {
+ suspend_current_and_run_next();
+ 0
+}
+
+pub fn sys_get_time() -> isize {
+ get_time_ms() as isize
}
-pub fn sys_get_time() -> isize {
- get_time_ms() as isize
+pub fn sys_getpid() -> isize {
+ current_task().unwrap().pid.0 as isize
}
-pub fn sys_getpid() -> isize {
- current_task().unwrap().pid.0 as isize
+pub fn sys_fork() -> isize {
+ let current_task = current_task().unwrap();
+ let new_task = current_task.fork();
+ let new_pid = new_task.pid.0;
+ // modify trap context of new_task, because it returns immediately after switching
+ let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
+ // we do not have to move to next instruction since we have done it before
+ // for child process, fork returns 0
+ trap_cx.x[10] = 0;
+ // add new task to scheduler
+ add_task(new_task);
+ new_pid as isize
}
-pub fn sys_fork() -> isize {
- let current_task = current_task().unwrap();
- let new_task = current_task.fork();
- let new_pid = new_task.pid.0;
- // modify trap context of new_task, because it returns immediately after switching
- let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
- // we do not have to move to next instruction since we have done it before
- // for child process, fork returns 0
- trap_cx.x[10] = 0;
- // add new task to scheduler
- add_task(new_task);
- new_pid as isize
+pub fn sys_exec(path: *const u8) -> isize {
+ let token = current_user_token();
+ let path = translated_str(token, path);
+ if let Some(data) = get_app_data_by_name(path.as_str()) {
+ let task = current_task().unwrap();
+ task.exec(data);
+ 0
+ } else {
+ -1
+ }
}
-pub fn sys_exec(path: *const u8) -> isize {
- let token = current_user_token();
- let path = translated_str(token, path);
- if let Some(data) = get_app_data_by_name(path.as_str()) {
- let task = current_task().unwrap();
- task.exec(data);
- 0
- } else {
- -1
- }
-}
+/// If there is not a child process whose pid is same as given, return -1.
+/// Else if there is a child process but it is still running, return -2.
+pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
+ let task = current_task().unwrap();
+ // find a child process
-/// If there is not a child process whose pid is same as given, return -1.
-/// Else if there is a child process but it is still running, return -2.
-pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
- let task = current_task().unwrap();
- // find a child process
-
- // ---- access current TCB exclusively
- let mut inner = task.inner_exclusive_access();
- if !inner
- .children
- .iter()
- .any(|p| pid == -1 || pid as usize == p.getpid())
+ // ---- access current TCB exclusively
+ let mut inner = task.inner_exclusive_access();
+ if !inner
+ .children
+ .iter()
+ .any(|p| pid == -1 || pid as usize == p.getpid())
{
- return -1;
- // ---- release current PCB
- }
- let pair = inner.children.iter().enumerate().find(|(_, p)| {
- // ++++ temporarily access child PCB lock exclusively
- p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid())
- // ++++ release child PCB
- });
- if let Some((idx, _)) = pair {
- let child = inner.children.remove(idx);
- // confirm that child will be deallocated after removing from children list
- assert_eq!(Arc::strong_count(&child), 1);
- let found_pid = child.getpid();
- // ++++ temporarily access child TCB exclusively
- let exit_code = child.inner_exclusive_access().exit_code;
- // ++++ release child PCB
- *translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code;
- found_pid as isize
- } else {
- -2
- }
- // ---- release current PCB lock automatically
-}
-
-
\ No newline at end of file
+ return -1;
+ // ---- release current PCB
+ }
+ let pair = inner.children.iter().enumerate().find(|(_, p)| {
+ // ++++ temporarily access child PCB lock exclusively
+ p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid())
+ // ++++ release child PCB
+ });
+ if let Some((idx, _)) = pair {
+ let child = inner.children.remove(idx);
+ // confirm that child will be deallocated after removing from children list
+ assert_eq!(Arc::strong_count(&child), 1);
+ let found_pid = child.getpid();
+ // ++++ temporarily access child TCB exclusively
+ let exit_code = child.inner_exclusive_access().exit_code;
+ // ++++ release child PCB
+ *translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code;
+ found_pid as isize
+ } else {
+ -2
+ }
+ // ---- release current PCB lock automatically
+}
+
\ No newline at end of file
diff --git a/ch5/src/os/task/context.rs.html b/ch5/src/os/task/context.rs.html
index d9e65cf1..f6f78874 100644
--- a/ch5/src/os/task/context.rs.html
+++ b/ch5/src/os/task/context.rs.html
@@ -1,66 +1,65 @@
-context.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-
//! Implementation of [`TaskContext`]
-use crate::trap::trap_return;
+context.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+
//! Implementation of [`TaskContext`]
+use crate::trap::trap_return;
-#[repr(C)]
-/// task context structure containing some registers
-pub struct TaskContext {
- /// return address ( e.g. __restore ) of __switch ASM function
- ra: usize,
- /// kernel stack pointer of app
- sp: usize,
- /// s0-11 register, callee saved
- s: [usize; 12],
+#[repr(C)]
+/// task context structure containing some registers
+pub struct TaskContext {
+ /// return address ( e.g. __restore ) of __switch ASM function
+ ra: usize,
+ /// kernel stack pointer of app
+ sp: usize,
+ /// s0-11 register, callee saved
+ s: [usize; 12],
}
-impl TaskContext {
- /// init task context
- pub fn zero_init() -> Self {
- Self {
- ra: 0,
- sp: 0,
- s: [0; 12],
+impl TaskContext {
+ /// init task context
+ pub fn zero_init() -> Self {
+ Self {
+ ra: 0,
+ sp: 0,
+ s: [0; 12],
}
}
- /// set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
- pub fn goto_trap_return(kstack_ptr: usize) -> Self {
- Self {
- ra: trap_return as usize,
- sp: kstack_ptr,
- s: [0; 12],
+ /// set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+ pub fn goto_trap_return(kstack_ptr: usize) -> Self {
+ Self {
+ ra: trap_return as usize,
+ sp: kstack_ptr,
+ s: [0; 12],
}
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/manager.rs.html b/ch5/src/os/task/manager.rs.html
index 71a3185a..47b41f43 100644
--- a/ch5/src/os/task/manager.rs.html
+++ b/ch5/src/os/task/manager.rs.html
@@ -1,84 +1,83 @@
-manager.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-
//!Implementation of [`TaskManager`]
-use super::TaskControlBlock;
-use crate::sync::UPSafeCell;
-use alloc::collections::VecDeque;
-use alloc::sync::Arc;
-use lazy_static::*;
-///A array of `TaskControlBlock` that is thread-safe
-pub struct TaskManager {
- ready_queue: VecDeque<Arc<TaskControlBlock>>,
+manager.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
//!Implementation of [`TaskManager`]
+use super::TaskControlBlock;
+use crate::sync::UPSafeCell;
+use alloc::collections::VecDeque;
+use alloc::sync::Arc;
+use lazy_static::*;
+///A array of `TaskControlBlock` that is thread-safe
+pub struct TaskManager {
+ ready_queue: VecDeque<Arc<TaskControlBlock>>,
}
-/// A simple FIFO scheduler.
-impl TaskManager {
- ///Creat an empty TaskManager
- pub fn new() -> Self {
- Self {
- ready_queue: VecDeque::new(),
+/// A simple FIFO scheduler.
+impl TaskManager {
+ ///Creat an empty TaskManager
+ pub fn new() -> Self {
+ Self {
+ ready_queue: VecDeque::new(),
}
}
- ///Add a task to `TaskManager`
- pub fn add(&mut self, task: Arc<TaskControlBlock>) {
- self.ready_queue.push_back(task);
+ ///Add a task to `TaskManager`
+ pub fn add(&mut self, task: Arc<TaskControlBlock>) {
+ self.ready_queue.push_back(task);
}
- ///Remove the first task and return it,or `None` if `TaskManager` is empty
- pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
- self.ready_queue.pop_front()
+ ///Remove the first task and return it,or `None` if `TaskManager` is empty
+ pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
+ self.ready_queue.pop_front()
}
}
-lazy_static! {
- pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
- unsafe { UPSafeCell::new(TaskManager::new()) };
+lazy_static! {
+ pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
+ unsafe { UPSafeCell::new(TaskManager::new()) };
}
-///Interface offered to add task
-pub fn add_task(task: Arc<TaskControlBlock>) {
- TASK_MANAGER.exclusive_access().add(task);
+///Interface offered to add task
+pub fn add_task(task: Arc<TaskControlBlock>) {
+ TASK_MANAGER.exclusive_access().add(task);
}
-///Interface offered to pop the first task
-pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
- TASK_MANAGER.exclusive_access().fetch()
+///Interface offered to pop the first task
+pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
+ TASK_MANAGER.exclusive_access().fetch()
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/mod.rs.html b/ch5/src/os/task/mod.rs.html
index b264e91d..cd9ea6da 100644
--- a/ch5/src/os/task/mod.rs.html
+++ b/ch5/src/os/task/mod.rs.html
@@ -1,244 +1,243 @@
-mod.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-
//! Task management implementation
-//!
-//! Everything about task management, like starting and switching tasks is
-//! implemented here.
-//!
-//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
-//! all the tasks in the whole operating system.
-//!
-//! A single global instance of [`Processor`] called `PROCESSOR` monitors running
-//! task(s) for each core.
-//!
-//! A single global instance of [`PidAllocator`] called `PID_ALLOCATOR` allocates
-//! pid for user apps.
-//!
-//! Be careful when you see `__switch` ASM function in `switch.S`. Control flow around this function
-//! might not be what you expect.
-mod context;
-mod manager;
-mod pid;
-mod processor;
-mod switch;
-#[allow(clippy::module_inception)]
-mod task;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+
//! Task management implementation
+//!
+//! Everything about task management, like starting and switching tasks is
+//! implemented here.
+//!
+//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
+//! all the tasks in the whole operating system.
+//!
+//! A single global instance of [`Processor`] called `PROCESSOR` monitors running
+//! task(s) for each core.
+//!
+//! A single global instance of [`PidAllocator`] called `PID_ALLOCATOR` allocates
+//! pid for user apps.
+//!
+//! Be careful when you see `__switch` ASM function in `switch.S`. Control flow around this function
+//! might not be what you expect.
+mod context;
+mod manager;
+mod pid;
+mod processor;
+mod switch;
+#[allow(clippy::module_inception)]
+mod task;
-use crate::loader::get_app_data_by_name;
-use crate::sbi::shutdown;
-use alloc::sync::Arc;
-use lazy_static::*;
-pub use manager::{fetch_task, TaskManager};
-use switch::__switch;
-use task::{TaskControlBlock, TaskStatus};
+use crate::loader::get_app_data_by_name;
+use crate::sbi::shutdown;
+use alloc::sync::Arc;
+use lazy_static::*;
+pub use manager::{fetch_task, TaskManager};
+use switch::__switch;
+use task::{TaskControlBlock, TaskStatus};
-pub use context::TaskContext;
-pub use manager::add_task;
-pub use pid::{pid_alloc, KernelStack, PidAllocator, PidHandle};
-pub use processor::{
- current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
- Processor,
+pub use context::TaskContext;
+pub use manager::add_task;
+pub use pid::{pid_alloc, KernelStack, PidAllocator, PidHandle};
+pub use processor::{
+ current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
+ Processor,
};
-/// Suspend the current 'Running' task and run the next task in task list.
-pub fn suspend_current_and_run_next() {
- // There must be an application running.
- let task = take_current_task().unwrap();
+/// Suspend the current 'Running' task and run the next task in task list.
+pub fn suspend_current_and_run_next() {
+ // There must be an application running.
+ let task = take_current_task().unwrap();
- // ---- access current TCB exclusively
- let mut task_inner = task.inner_exclusive_access();
- let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
- // Change status to Ready
- task_inner.task_status = TaskStatus::Ready;
- drop(task_inner);
- // ---- release current PCB
+ // ---- access current TCB exclusively
+ let mut task_inner = task.inner_exclusive_access();
+ let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
+ // Change status to Ready
+ task_inner.task_status = TaskStatus::Ready;
+ drop(task_inner);
+ // ---- release current PCB
- // push back to ready queue.
- add_task(task);
- // jump to scheduling cycle
- schedule(task_cx_ptr);
+ // push back to ready queue.
+ add_task(task);
+ // jump to scheduling cycle
+ schedule(task_cx_ptr);
}
-/// pid of usertests app in make run TEST=1
-pub const IDLE_PID: usize = 0;
+/// pid of usertests app in make run TEST=1
+pub const IDLE_PID: usize = 0;
-/// Exit the current 'Running' task and run the next task in task list.
-pub fn exit_current_and_run_next(exit_code: i32) {
- // take from Processor
- let task = take_current_task().unwrap();
+/// Exit the current 'Running' task and run the next task in task list.
+pub fn exit_current_and_run_next(exit_code: i32) {
+ // take from Processor
+ let task = take_current_task().unwrap();
- let pid = task.getpid();
- if pid == IDLE_PID {
+ let pid = task.getpid();
+ if pid == IDLE_PID {
println!(
"[kernel] Idle process exit with exit_code {} ...",
- exit_code
+ exit_code
);
- if exit_code != 0 {
- //crate::sbi::shutdown(255); //255 == -1 for err hint
- shutdown(true)
- } else {
- //crate::sbi::shutdown(0); //0 for success hint
- shutdown(false)
+ if exit_code != 0 {
+ //crate::sbi::shutdown(255); //255 == -1 for err hint
+ shutdown(true)
+ } else {
+ //crate::sbi::shutdown(0); //0 for success hint
+ shutdown(false)
}
}
- // **** access current TCB exclusively
- let mut inner = task.inner_exclusive_access();
- // Change status to Zombie
- inner.task_status = TaskStatus::Zombie;
- // Record exit code
- inner.exit_code = exit_code;
- // do not move to its parent but under initproc
+ // **** access current TCB exclusively
+ let mut inner = task.inner_exclusive_access();
+ // Change status to Zombie
+ inner.task_status = TaskStatus::Zombie;
+ // Record exit code
+ inner.exit_code = exit_code;
+ // do not move to its parent but under initproc
- // ++++++ access initproc TCB exclusively
- {
- let mut initproc_inner = INITPROC.inner_exclusive_access();
- for child in inner.children.iter() {
- child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
- initproc_inner.children.push(child.clone());
+ // ++++++ access initproc TCB exclusively
+ {
+ let mut initproc_inner = INITPROC.inner_exclusive_access();
+ for child in inner.children.iter() {
+ child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
+ initproc_inner.children.push(child.clone());
}
}
- // ++++++ release parent PCB
+ // ++++++ release parent PCB
- inner.children.clear();
- // deallocate user space
- inner.memory_set.recycle_data_pages();
- drop(inner);
- // **** release current PCB
- // drop task manually to maintain rc correctly
- drop(task);
- // we do not have to save task context
- let mut _unused = TaskContext::zero_init();
- schedule(&mut _unused as *mut _);
+ inner.children.clear();
+ // deallocate user space
+ inner.memory_set.recycle_data_pages();
+ drop(inner);
+ // **** release current PCB
+ // drop task manually to maintain rc correctly
+ drop(task);
+ // we do not have to save task context
+ let mut _unused = TaskContext::zero_init();
+ schedule(&mut _unused as *mut _);
}
-lazy_static! {
- ///Globle process that init user shell
- pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new(TaskControlBlock::new(
- get_app_data_by_name("initproc").unwrap()
+lazy_static! {
+ ///Globle process that init user shell
+ pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new(TaskControlBlock::new(
+ get_app_data_by_name("initproc").unwrap()
));
}
-///Add init process to the manager
-pub fn add_initproc() {
- add_task(INITPROC.clone());
+///Add init process to the manager
+pub fn add_initproc() {
+ add_task(INITPROC.clone());
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/pid.rs.html b/ch5/src/os/task/pid.rs.html
index 4d46c8aa..4d55c2bf 100644
--- a/ch5/src/os/task/pid.rs.html
+++ b/ch5/src/os/task/pid.rs.html
@@ -1,224 +1,223 @@
-pid.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-
//!Implementation of [`PidAllocator`]
-use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE};
-use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE};
-use crate::sync::UPSafeCell;
-use alloc::vec::Vec;
-use lazy_static::*;
-///Pid Allocator struct
-pub struct PidAllocator {
- current: usize,
- recycled: Vec<usize>,
+pid.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+
//!Implementation of [`PidAllocator`]
+use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE};
+use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE};
+use crate::sync::UPSafeCell;
+use alloc::vec::Vec;
+use lazy_static::*;
+///Pid Allocator struct
+pub struct PidAllocator {
+ current: usize,
+ recycled: Vec<usize>,
}
-impl PidAllocator {
- ///Create an empty `PidAllocator`
- pub fn new() -> Self {
- PidAllocator {
- current: 0,
- recycled: Vec::new(),
+impl PidAllocator {
+ ///Create an empty `PidAllocator`
+ pub fn new() -> Self {
+ PidAllocator {
+ current: 0,
+ recycled: Vec::new(),
}
}
- ///Allocate a pid
- pub fn alloc(&mut self) -> PidHandle {
- if let Some(pid) = self.recycled.pop() {
- PidHandle(pid)
- } else {
- self.current += 1;
- PidHandle(self.current - 1)
+ ///Allocate a pid
+ pub fn alloc(&mut self) -> PidHandle {
+ if let Some(pid) = self.recycled.pop() {
+ PidHandle(pid)
+ } else {
+ self.current += 1;
+ PidHandle(self.current - 1)
}
}
- ///Recycle a pid
- pub fn dealloc(&mut self, pid: usize) {
- assert!(pid < self.current);
+ ///Recycle a pid
+ pub fn dealloc(&mut self, pid: usize) {
+ assert!(pid < self.current);
assert!(
- !self.recycled.iter().any(|ppid| *ppid == pid),
+ !self.recycled.iter().any(|ppid| *ppid == pid),
"pid {} has been deallocated!",
- pid
+ pid
);
- self.recycled.push(pid);
+ self.recycled.push(pid);
}
}
-lazy_static! {
- pub static ref PID_ALLOCATOR: UPSafeCell<PidAllocator> =
- unsafe { UPSafeCell::new(PidAllocator::new()) };
+lazy_static! {
+ pub static ref PID_ALLOCATOR: UPSafeCell<PidAllocator> =
+ unsafe { UPSafeCell::new(PidAllocator::new()) };
}
-///Bind pid lifetime to `PidHandle`
-pub struct PidHandle(pub usize);
+///Bind pid lifetime to `PidHandle`
+pub struct PidHandle(pub usize);
-impl Drop for PidHandle {
- fn drop(&mut self) {
- //println!("drop pid {}", self.0);
- PID_ALLOCATOR.exclusive_access().dealloc(self.0);
+impl Drop for PidHandle {
+ fn drop(&mut self) {
+ //println!("drop pid {}", self.0);
+ PID_ALLOCATOR.exclusive_access().dealloc(self.0);
}
}
-///Allocate a pid from PID_ALLOCATOR
-pub fn pid_alloc() -> PidHandle {
- PID_ALLOCATOR.exclusive_access().alloc()
+///Allocate a pid from PID_ALLOCATOR
+pub fn pid_alloc() -> PidHandle {
+ PID_ALLOCATOR.exclusive_access().alloc()
}
-/// Return (bottom, top) of a kernel stack in kernel space.
-pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
- let top = TRAMPOLINE - app_id * (KERNEL_STACK_SIZE + PAGE_SIZE);
- let bottom = top - KERNEL_STACK_SIZE;
- (bottom, top)
+/// Return (bottom, top) of a kernel stack in kernel space.
+pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
+ let top = TRAMPOLINE - app_id * (KERNEL_STACK_SIZE + PAGE_SIZE);
+ let bottom = top - KERNEL_STACK_SIZE;
+ (bottom, top)
}
-///Kernelstack for app
-pub struct KernelStack {
- pid: usize,
+///Kernelstack for app
+pub struct KernelStack {
+ pid: usize,
}
-impl KernelStack {
- ///Create a kernelstack from pid
- pub fn new(pid_handle: &PidHandle) -> Self {
- let pid = pid_handle.0;
- let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(pid);
- KERNEL_SPACE.exclusive_access().insert_framed_area(
- kernel_stack_bottom.into(),
- kernel_stack_top.into(),
- MapPermission::R | MapPermission::W,
+impl KernelStack {
+ ///Create a kernelstack from pid
+ pub fn new(pid_handle: &PidHandle) -> Self {
+ let pid = pid_handle.0;
+ let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(pid);
+ KERNEL_SPACE.exclusive_access().insert_framed_area(
+ kernel_stack_bottom.into(),
+ kernel_stack_top.into(),
+ MapPermission::R | MapPermission::W,
);
- KernelStack { pid: pid_handle.0 }
+ KernelStack { pid: pid_handle.0 }
}
- #[allow(unused)]
- ///Push a value on top of kernelstack
- pub fn push_on_top<T>(&self, value: T) -> *mut T
- where
- T: Sized,
+ #[allow(unused)]
+ ///Push a value on top of kernelstack
+ pub fn push_on_top<T>(&self, value: T) -> *mut T
+ where
+ T: Sized,
{
- let kernel_stack_top = self.get_top();
- let ptr_mut = (kernel_stack_top - core::mem::size_of::<T>()) as *mut T;
- unsafe {
- *ptr_mut = value;
+ let kernel_stack_top = self.get_top();
+ let ptr_mut = (kernel_stack_top - core::mem::size_of::<T>()) as *mut T;
+ unsafe {
+ *ptr_mut = value;
}
- ptr_mut
+ ptr_mut
}
- ///Get the value on the top of kernelstack
- pub fn get_top(&self) -> usize {
- let (_, kernel_stack_top) = kernel_stack_position(self.pid);
- kernel_stack_top
+ ///Get the value on the top of kernelstack
+ pub fn get_top(&self) -> usize {
+ let (_, kernel_stack_top) = kernel_stack_position(self.pid);
+ kernel_stack_top
}
}
-impl Drop for KernelStack {
- fn drop(&mut self) {
- let (kernel_stack_bottom, _) = kernel_stack_position(self.pid);
- let kernel_stack_bottom_va: VirtAddr = kernel_stack_bottom.into();
- KERNEL_SPACE
- .exclusive_access()
- .remove_area_with_start_vpn(kernel_stack_bottom_va.into());
+impl Drop for KernelStack {
+ fn drop(&mut self) {
+ let (kernel_stack_bottom, _) = kernel_stack_position(self.pid);
+ let kernel_stack_bottom_va: VirtAddr = kernel_stack_bottom.into();
+ KERNEL_SPACE
+ .exclusive_access()
+ .remove_area_with_start_vpn(kernel_stack_bottom_va.into());
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/processor.rs.html b/ch5/src/os/task/processor.rs.html
index 078d5746..39c529dc 100644
--- a/ch5/src/os/task/processor.rs.html
+++ b/ch5/src/os/task/processor.rs.html
@@ -1,188 +1,187 @@
-processor.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-
//!Implementation of [`Processor`] and Intersection of control flow
-use super::__switch;
-use super::{fetch_task, TaskStatus};
-use super::{TaskContext, TaskControlBlock};
-use crate::sync::UPSafeCell;
-use crate::trap::TrapContext;
-use alloc::sync::Arc;
-use lazy_static::*;
-///Processor management structure
-pub struct Processor {
- ///The task currently executing on the current processor
- current: Option<Arc<TaskControlBlock>>,
- ///The basic control flow of each core, helping to select and switch process
- idle_task_cx: TaskContext,
+processor.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+
//!Implementation of [`Processor`] and Intersection of control flow
+use super::__switch;
+use super::{fetch_task, TaskStatus};
+use super::{TaskContext, TaskControlBlock};
+use crate::sync::UPSafeCell;
+use crate::trap::TrapContext;
+use alloc::sync::Arc;
+use lazy_static::*;
+///Processor management structure
+pub struct Processor {
+ ///The task currently executing on the current processor
+ current: Option<Arc<TaskControlBlock>>,
+ ///The basic control flow of each core, helping to select and switch process
+ idle_task_cx: TaskContext,
}
-impl Processor {
- ///Create an empty Processor
- pub fn new() -> Self {
- Self {
- current: None,
- idle_task_cx: TaskContext::zero_init(),
+impl Processor {
+ ///Create an empty Processor
+ pub fn new() -> Self {
+ Self {
+ current: None,
+ idle_task_cx: TaskContext::zero_init(),
}
}
- ///Get mutable reference to `idle_task_cx`
- fn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext {
- &mut self.idle_task_cx as *mut _
+ ///Get mutable reference to `idle_task_cx`
+ fn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext {
+ &mut self.idle_task_cx as *mut _
+ }
+ ///Get current task in moving semanteme
+ pub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>> {
+ self.current.take()
}
- ///Get current task in moving semanteme
- pub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>> {
- self.current.take()
- }
- ///Get current task in cloning semanteme
- pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
- self.current.as_ref().map(Arc::clone)
+ ///Get current task in cloning semanteme
+ pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
+ self.current.as_ref().map(Arc::clone)
}
}
-lazy_static! {
- pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
+lazy_static! {
+ pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
}
-///The main part of process execution and scheduling
-///Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`
-pub fn run_tasks() {
- loop {
- let mut processor = PROCESSOR.exclusive_access();
- if let Some(task) = fetch_task() {
- let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
- // access coming task TCB exclusively
- let mut task_inner = task.inner_exclusive_access();
- let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
- task_inner.task_status = TaskStatus::Running;
- drop(task_inner);
- // release coming task TCB manually
- processor.current = Some(task);
- // release processor manually
- drop(processor);
- unsafe {
- __switch(idle_task_cx_ptr, next_task_cx_ptr);
+///The main part of process execution and scheduling
+///Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`
+pub fn run_tasks() {
+ loop {
+ let mut processor = PROCESSOR.exclusive_access();
+ if let Some(task) = fetch_task() {
+ let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
+ // access coming task TCB exclusively
+ let mut task_inner = task.inner_exclusive_access();
+ let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
+ task_inner.task_status = TaskStatus::Running;
+ drop(task_inner);
+ // release coming task TCB manually
+ processor.current = Some(task);
+ // release processor manually
+ drop(processor);
+ unsafe {
+ __switch(idle_task_cx_ptr, next_task_cx_ptr);
}
}
}
}
-///Take the current task,leaving a None in its place
-pub fn take_current_task() -> Option<Arc<TaskControlBlock>> {
- PROCESSOR.exclusive_access().take_current()
+///Take the current task,leaving a None in its place
+pub fn take_current_task() -> Option<Arc<TaskControlBlock>> {
+ PROCESSOR.exclusive_access().take_current()
}
-///Get running task
-pub fn current_task() -> Option<Arc<TaskControlBlock>> {
- PROCESSOR.exclusive_access().current()
+///Get running task
+pub fn current_task() -> Option<Arc<TaskControlBlock>> {
+ PROCESSOR.exclusive_access().current()
}
-///Get token of the address space of current task
-pub fn current_user_token() -> usize {
- let task = current_task().unwrap();
- let token = task.inner_exclusive_access().get_user_token();
- token
+///Get token of the address space of current task
+pub fn current_user_token() -> usize {
+ let task = current_task().unwrap();
+ let token = task.inner_exclusive_access().get_user_token();
+ token
}
-///Get the mutable reference to trap context of current task
-pub fn current_trap_cx() -> &'static mut TrapContext {
- current_task()
- .unwrap()
- .inner_exclusive_access()
- .get_trap_cx()
+///Get the mutable reference to trap context of current task
+pub fn current_trap_cx() -> &'static mut TrapContext {
+ current_task()
+ .unwrap()
+ .inner_exclusive_access()
+ .get_trap_cx()
}
-///Return to idle control flow for new scheduling
-pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
- let mut processor = PROCESSOR.exclusive_access();
- let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
- drop(processor);
- unsafe {
- __switch(switched_task_cx_ptr, idle_task_cx_ptr);
+///Return to idle control flow for new scheduling
+pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
+ let mut processor = PROCESSOR.exclusive_access();
+ let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
+ drop(processor);
+ unsafe {
+ __switch(switched_task_cx_ptr, idle_task_cx_ptr);
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/switch.rs.html b/ch5/src/os/task/switch.rs.html
index 191a95d6..a14b8a8e 100644
--- a/ch5/src/os/task/switch.rs.html
+++ b/ch5/src/os/task/switch.rs.html
@@ -1,20 +1,19 @@
-switch.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-
//!Wrap `switch.S` as a function
-use super::TaskContext;
-use core::arch::global_asm;
+switch.rs - source //!Wrap `switch.S` as a function
+use super::TaskContext;
+use core::arch::global_asm;
global_asm!(include_str!("switch.S"));
-extern "C" {
- pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
+extern "C" {
+ pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/task/task.rs.html b/ch5/src/os/task/task.rs.html
index b5af4248..cc18b38a 100644
--- a/ch5/src/os/task/task.rs.html
+++ b/ch5/src/os/task/task.rs.html
@@ -1,344 +1,343 @@
-task.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-
//!Implementation of [`TaskControlBlock`]
-use super::TaskContext;
-use super::{pid_alloc, KernelStack, PidHandle};
-use crate::config::TRAP_CONTEXT;
-use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE};
-use crate::sync::UPSafeCell;
-use crate::trap::{trap_handler, TrapContext};
-use alloc::sync::{Arc, Weak};
-use alloc::vec::Vec;
-use core::cell::RefMut;
+task.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+
//!Implementation of [`TaskControlBlock`]
+use super::TaskContext;
+use super::{pid_alloc, KernelStack, PidHandle};
+use crate::config::TRAP_CONTEXT;
+use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE};
+use crate::sync::UPSafeCell;
+use crate::trap::{trap_handler, TrapContext};
+use alloc::sync::{Arc, Weak};
+use alloc::vec::Vec;
+use core::cell::RefMut;
-pub struct TaskControlBlock {
- // immutable
- pub pid: PidHandle,
- pub kernel_stack: KernelStack,
- // mutable
- inner: UPSafeCell<TaskControlBlockInner>,
+pub struct TaskControlBlock {
+ // immutable
+ pub pid: PidHandle,
+ pub kernel_stack: KernelStack,
+ // mutable
+ inner: UPSafeCell<TaskControlBlockInner>,
}
-pub struct TaskControlBlockInner {
- pub trap_cx_ppn: PhysPageNum,
- pub base_size: usize,
- pub task_cx: TaskContext,
- pub task_status: TaskStatus,
- pub memory_set: MemorySet,
- pub parent: Option<Weak<TaskControlBlock>>,
- pub children: Vec<Arc<TaskControlBlock>>,
- pub exit_code: i32,
+pub struct TaskControlBlockInner {
+ pub trap_cx_ppn: PhysPageNum,
+ pub base_size: usize,
+ pub task_cx: TaskContext,
+ pub task_status: TaskStatus,
+ pub memory_set: MemorySet,
+ pub parent: Option<Weak<TaskControlBlock>>,
+ pub children: Vec<Arc<TaskControlBlock>>,
+ pub exit_code: i32,
}
-impl TaskControlBlockInner {
+impl TaskControlBlockInner {
/*
pub fn get_task_cx_ptr2(&self) -> *const usize {
&self.task_cx_ptr as *const usize
}
- */
- pub fn get_trap_cx(&self) -> &'static mut TrapContext {
- self.trap_cx_ppn.get_mut()
+ */
+ pub fn get_trap_cx(&self) -> &'static mut TrapContext {
+ self.trap_cx_ppn.get_mut()
}
- pub fn get_user_token(&self) -> usize {
- self.memory_set.token()
+ pub fn get_user_token(&self) -> usize {
+ self.memory_set.token()
}
- fn get_status(&self) -> TaskStatus {
- self.task_status
+ fn get_status(&self) -> TaskStatus {
+ self.task_status
}
- pub fn is_zombie(&self) -> bool {
- self.get_status() == TaskStatus::Zombie
+ pub fn is_zombie(&self) -> bool {
+ self.get_status() == TaskStatus::Zombie
}
}
-impl TaskControlBlock {
- pub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner> {
- self.inner.exclusive_access()
+impl TaskControlBlock {
+ pub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner> {
+ self.inner.exclusive_access()
}
- pub fn new(elf_data: &[u8]) -> Self {
- // memory_set with elf program headers/trampoline/trap context/user stack
- let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
- // alloc a pid and a kernel stack in kernel space
- let pid_handle = pid_alloc();
- let kernel_stack = KernelStack::new(&pid_handle);
- let kernel_stack_top = kernel_stack.get_top();
- // push a task context which goes to trap_return to the top of kernel stack
- let task_control_block = Self {
- pid: pid_handle,
- kernel_stack,
- inner: unsafe {
- UPSafeCell::new(TaskControlBlockInner {
- trap_cx_ppn,
- base_size: user_sp,
- task_cx: TaskContext::goto_trap_return(kernel_stack_top),
- task_status: TaskStatus::Ready,
- memory_set,
- parent: None,
- children: Vec::new(),
- exit_code: 0,
+ pub fn new(elf_data: &[u8]) -> Self {
+ // memory_set with elf program headers/trampoline/trap context/user stack
+ let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
+ // alloc a pid and a kernel stack in kernel space
+ let pid_handle = pid_alloc();
+ let kernel_stack = KernelStack::new(&pid_handle);
+ let kernel_stack_top = kernel_stack.get_top();
+ // push a task context which goes to trap_return to the top of kernel stack
+ let task_control_block = Self {
+ pid: pid_handle,
+ kernel_stack,
+ inner: unsafe {
+ UPSafeCell::new(TaskControlBlockInner {
+ trap_cx_ppn,
+ base_size: user_sp,
+ task_cx: TaskContext::goto_trap_return(kernel_stack_top),
+ task_status: TaskStatus::Ready,
+ memory_set,
+ parent: None,
+ children: Vec::new(),
+ exit_code: 0,
})
},
};
- // prepare TrapContext in user space
- let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
- *trap_cx = TrapContext::app_init_context(
- entry_point,
- user_sp,
- KERNEL_SPACE.exclusive_access().token(),
- kernel_stack_top,
- trap_handler as usize,
+ // prepare TrapContext in user space
+ let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
+ *trap_cx = TrapContext::app_init_context(
+ entry_point,
+ user_sp,
+ KERNEL_SPACE.exclusive_access().token(),
+ kernel_stack_top,
+ trap_handler as usize,
);
- task_control_block
+ task_control_block
}
- pub fn exec(&self, elf_data: &[u8]) {
- // memory_set with elf program headers/trampoline/trap context/user stack
- let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
+ pub fn exec(&self, elf_data: &[u8]) {
+ // memory_set with elf program headers/trampoline/trap context/user stack
+ let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
- // **** access inner exclusively
- let mut inner = self.inner_exclusive_access();
- // substitute memory_set
- inner.memory_set = memory_set;
- // update trap_cx ppn
- inner.trap_cx_ppn = trap_cx_ppn;
- // initialize base_size
- inner.base_size = user_sp;
- // initialize trap_cx
- let trap_cx = inner.get_trap_cx();
- *trap_cx = TrapContext::app_init_context(
- entry_point,
- user_sp,
- KERNEL_SPACE.exclusive_access().token(),
- self.kernel_stack.get_top(),
- trap_handler as usize,
+ // **** access inner exclusively
+ let mut inner = self.inner_exclusive_access();
+ // substitute memory_set
+ inner.memory_set = memory_set;
+ // update trap_cx ppn
+ inner.trap_cx_ppn = trap_cx_ppn;
+ // initialize base_size
+ inner.base_size = user_sp;
+ // initialize trap_cx
+ let trap_cx = inner.get_trap_cx();
+ *trap_cx = TrapContext::app_init_context(
+ entry_point,
+ user_sp,
+ KERNEL_SPACE.exclusive_access().token(),
+ self.kernel_stack.get_top(),
+ trap_handler as usize,
);
- // **** release inner automatically
- }
- pub fn fork(self: &Arc<Self>) -> Arc<Self> {
- // ---- access parent PCB exclusively
- let mut parent_inner = self.inner_exclusive_access();
- // copy user space(include trap context)
- let memory_set = MemorySet::from_existed_user(&parent_inner.memory_set);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
- // alloc a pid and a kernel stack in kernel space
- let pid_handle = pid_alloc();
- let kernel_stack = KernelStack::new(&pid_handle);
- let kernel_stack_top = kernel_stack.get_top();
- let task_control_block = Arc::new(TaskControlBlock {
- pid: pid_handle,
- kernel_stack,
- inner: unsafe {
- UPSafeCell::new(TaskControlBlockInner {
- trap_cx_ppn,
- base_size: parent_inner.base_size,
- task_cx: TaskContext::goto_trap_return(kernel_stack_top),
- task_status: TaskStatus::Ready,
- memory_set,
- parent: Some(Arc::downgrade(self)),
- children: Vec::new(),
- exit_code: 0,
+ // **** release inner automatically
+ }
+ pub fn fork(self: &Arc<Self>) -> Arc<Self> {
+ // ---- access parent PCB exclusively
+ let mut parent_inner = self.inner_exclusive_access();
+ // copy user space(include trap context)
+ let memory_set = MemorySet::from_existed_user(&parent_inner.memory_set);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
+ // alloc a pid and a kernel stack in kernel space
+ let pid_handle = pid_alloc();
+ let kernel_stack = KernelStack::new(&pid_handle);
+ let kernel_stack_top = kernel_stack.get_top();
+ let task_control_block = Arc::new(TaskControlBlock {
+ pid: pid_handle,
+ kernel_stack,
+ inner: unsafe {
+ UPSafeCell::new(TaskControlBlockInner {
+ trap_cx_ppn,
+ base_size: parent_inner.base_size,
+ task_cx: TaskContext::goto_trap_return(kernel_stack_top),
+ task_status: TaskStatus::Ready,
+ memory_set,
+ parent: Some(Arc::downgrade(self)),
+ children: Vec::new(),
+ exit_code: 0,
})
},
});
- // add child
- parent_inner.children.push(task_control_block.clone());
- // modify kernel_sp in trap_cx
- // **** access children PCB exclusively
- let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
- trap_cx.kernel_sp = kernel_stack_top;
- // return
- task_control_block
- // ---- release parent PCB automatically
- // **** release children PCB automatically
- }
- pub fn getpid(&self) -> usize {
- self.pid.0
- }
+ // add child
+ parent_inner.children.push(task_control_block.clone());
+ // modify kernel_sp in trap_cx
+ // **** access children PCB exclusively
+ let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
+ trap_cx.kernel_sp = kernel_stack_top;
+ // return
+ task_control_block
+ // ---- release parent PCB automatically
+ // **** release children PCB automatically
+ }
+ pub fn getpid(&self) -> usize {
+ self.pid.0
+ }
}
-#[derive(Copy, Clone, PartialEq)]
-pub enum TaskStatus {
- Ready,
- Running,
- Zombie,
+#[derive(Copy, Clone, PartialEq)]
+pub enum TaskStatus {
+ Ready,
+ Running,
+ Zombie,
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/timer.rs.html b/ch5/src/os/timer.rs.html
index b6c263b1..d4830ce5 100644
--- a/ch5/src/os/timer.rs.html
+++ b/ch5/src/os/timer.rs.html
@@ -1,42 +1,41 @@
-timer.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-
//! RISC-V timer-related functionality
+timer.rs - source //! RISC-V timer-related functionality
-use crate::config::CLOCK_FREQ;
-use crate::sbi::set_timer;
-use riscv::register::time;
+use crate::config::CLOCK_FREQ;
+use crate::sbi::set_timer;
+use riscv::register::time;
-const TICKS_PER_SEC: usize = 100;
-const MSEC_PER_SEC: usize = 1000;
-///get current time
-pub fn get_time() -> usize {
- time::read()
+const TICKS_PER_SEC: usize = 100;
+const MSEC_PER_SEC: usize = 1000;
+///get current time
+pub fn get_time() -> usize {
+ time::read()
}
-/// get current time in microseconds
-pub fn get_time_ms() -> usize {
- time::read() / (CLOCK_FREQ / MSEC_PER_SEC)
+/// get current time in microseconds
+pub fn get_time_ms() -> usize {
+ time::read() / (CLOCK_FREQ / MSEC_PER_SEC)
}
-/// set the next timer interrupt
-pub fn set_next_trigger() {
- set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC);
+/// set the next timer interrupt
+pub fn set_next_trigger() {
+ set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC);
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/trap/context.rs.html b/ch5/src/os/trap/context.rs.html
index 9e87e174..74b6252d 100644
--- a/ch5/src/os/trap/context.rs.html
+++ b/ch5/src/os/trap/context.rs.html
@@ -1,98 +1,97 @@
-context.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-
//! Implementation of [`TrapContext`]
-use riscv::register::sstatus::{self, Sstatus, SPP};
+context.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+
//! Implementation of [`TrapContext`]
+use riscv::register::sstatus::{self, Sstatus, SPP};
-#[repr(C)]
-///trap context structure containing sstatus, sepc and registers
-pub struct TrapContext {
- /// general regs[0..31]
- pub x: [usize; 32],
- /// CSR sstatus
- pub sstatus: Sstatus,
- /// CSR sepc
- pub sepc: usize,
- /// Addr of Page Table
- pub kernel_satp: usize,
- /// kernel stack
- pub kernel_sp: usize,
- /// Addr of trap_handler function
- pub trap_handler: usize,
+#[repr(C)]
+///trap context structure containing sstatus, sepc and registers
+pub struct TrapContext {
+ /// general regs[0..31]
+ pub x: [usize; 32],
+ /// CSR sstatus
+ pub sstatus: Sstatus,
+ /// CSR sepc
+ pub sepc: usize,
+ /// Addr of Page Table
+ pub kernel_satp: usize,
+ /// kernel stack
+ pub kernel_sp: usize,
+ /// Addr of trap_handler function
+ pub trap_handler: usize,
}
-impl TrapContext {
- ///set stack pointer to x_2 reg (sp)
- pub fn set_sp(&mut self, sp: usize) {
- self.x[2] = sp;
+impl TrapContext {
+ ///set stack pointer to x_2 reg (sp)
+ pub fn set_sp(&mut self, sp: usize) {
+ self.x[2] = sp;
}
- ///init app context
- pub fn app_init_context(
- entry: usize,
- sp: usize,
- kernel_satp: usize,
- kernel_sp: usize,
- trap_handler: usize,
- ) -> Self {
- let mut sstatus = sstatus::read();
- // set CPU privilege to User after trapping back
- sstatus.set_spp(SPP::User);
- let mut cx = Self {
- x: [0; 32],
- sstatus,
- sepc: entry,
- kernel_satp,
- kernel_sp,
- trap_handler,
+ ///init app context
+ pub fn app_init_context(
+ entry: usize,
+ sp: usize,
+ kernel_satp: usize,
+ kernel_sp: usize,
+ trap_handler: usize,
+ ) -> Self {
+ let mut sstatus = sstatus::read();
+ // set CPU privilege to User after trapping back
+ sstatus.set_spp(SPP::User);
+ let mut cx = Self {
+ x: [0; 32],
+ sstatus,
+ sepc: entry,
+ kernel_satp,
+ kernel_sp,
+ trap_handler,
};
- cx.set_sp(sp);
- cx
+ cx.set_sp(sp);
+ cx
}
}
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ch5/src/os/trap/mod.rs.html b/ch5/src/os/trap/mod.rs.html
index f93e2d8f..d970ec17 100644
--- a/ch5/src/os/trap/mod.rs.html
+++ b/ch5/src/os/trap/mod.rs.html
@@ -1,276 +1,275 @@
-mod.rs - source 1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
-62
-63
-64
-65
-66
-67
-68
-69
-70
-71
-72
-73
-74
-75
-76
-77
-78
-79
-80
-81
-82
-83
-84
-85
-86
-87
-88
-89
-90
-91
-92
-93
-94
-95
-96
-97
-98
-99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-
//! Trap handling functionality
-//!
-//! For rCore, we have a single trap entry point, namely `__alltraps`. At
-//! initialization in [`init()`], we set the `stvec` CSR to point to it.
-//!
-//! All traps go through `__alltraps`, which is defined in `trap.S`. The
-//! assembly language code does just enough work restore the kernel space
-//! context, ensuring that Rust code safely runs, and transfers control to
-//! [`trap_handler()`].
-//!
-//! It then calls different functionality based on what exactly the exception
-//! was. For example, timer interrupts trigger task preemption, and syscalls go
-//! to [`syscall()`].
-mod context;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+
//! Trap handling functionality
+//!
+//! For rCore, we have a single trap entry point, namely `__alltraps`. At
+//! initialization in [`init()`], we set the `stvec` CSR to point to it.
+//!
+//! All traps go through `__alltraps`, which is defined in `trap.S`. The
+//! assembly language code does just enough work restore the kernel space
+//! context, ensuring that Rust code safely runs, and transfers control to
+//! [`trap_handler()`].
+//!
+//! It then calls different functionality based on what exactly the exception
+//! was. For example, timer interrupts trigger task preemption, and syscalls go
+//! to [`syscall()`].
+mod context;
-use crate::config::{TRAMPOLINE, TRAP_CONTEXT};
-use crate::syscall::syscall;
-use crate::task::{
- current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next,
+use crate::config::{TRAMPOLINE, TRAP_CONTEXT};
+use crate::syscall::syscall;
+use crate::task::{
+ current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next,
};
-use crate::timer::set_next_trigger;
-use core::arch::{asm, global_asm};
-use riscv::register::{
- mtvec::TrapMode,
- scause::{self, Exception, Interrupt, Trap},
- sie, stval, stvec,
+use crate::timer::set_next_trigger;
+use core::arch::{asm, global_asm};
+use riscv::register::{
+ mtvec::TrapMode,
+ scause::{self, Exception, Interrupt, Trap},
+ sie, stval, stvec,
};
global_asm!(include_str!("trap.S"));
-/// initialize CSR `stvec` as the entry of `__alltraps`
-pub fn init() {
- set_kernel_trap_entry();
+/// initialize CSR `stvec` as the entry of `__alltraps`
+pub fn init() {
+ set_kernel_trap_entry();
}
-fn set_kernel_trap_entry() {
- unsafe {
- stvec::write(trap_from_kernel as usize, TrapMode::Direct);
+fn set_kernel_trap_entry() {
+ unsafe {
+ stvec::write(trap_from_kernel as usize, TrapMode::Direct);
}
}
-fn set_user_trap_entry() {
- unsafe {
- stvec::write(TRAMPOLINE as usize, TrapMode::Direct);
+fn set_user_trap_entry() {
+ unsafe {
+ stvec::write(TRAMPOLINE as usize, TrapMode::Direct);
}
}
-/// enable timer interrupt in sie CSR
-pub fn enable_timer_interrupt() {
- unsafe {
- sie::set_stimer();
+/// enable timer interrupt in sie CSR
+pub fn enable_timer_interrupt() {
+ unsafe {
+ sie::set_stimer();
}
}
-#[no_mangle]
-/// handle an interrupt, exception, or system call from user space
-pub fn trap_handler() -> ! {
- set_kernel_trap_entry();
- let scause = scause::read();
- let stval = stval::read();
- match scause.cause() {
- Trap::Exception(Exception::UserEnvCall) => {
- // jump to next instruction anyway
- let mut cx = current_trap_cx();
- cx.sepc += 4;
- // get system call return value
- let result = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]);
- // cx is changed during sys_exec, so we have to call it again
- cx = current_trap_cx();
- cx.x[10] = result as usize;
+#[no_mangle]
+/// handle an interrupt, exception, or system call from user space
+pub fn trap_handler() -> ! {
+ set_kernel_trap_entry();
+ let scause = scause::read();
+ let stval = stval::read();
+ match scause.cause() {
+ Trap::Exception(Exception::UserEnvCall) => {
+ // jump to next instruction anyway
+ let mut cx = current_trap_cx();
+ cx.sepc += 4;
+ // get system call return value
+ let result = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]);
+ // cx is changed during sys_exec, so we have to call it again
+ cx = current_trap_cx();
+ cx.x[10] = result as usize;
}
- Trap::Exception(Exception::StoreFault)
- | Trap::Exception(Exception::StorePageFault)
- | Trap::Exception(Exception::InstructionFault)
- | Trap::Exception(Exception::InstructionPageFault)
- | Trap::Exception(Exception::LoadFault)
- | Trap::Exception(Exception::LoadPageFault) => {
+ Trap::Exception(Exception::StoreFault)
+ | Trap::Exception(Exception::StorePageFault)
+ | Trap::Exception(Exception::InstructionFault)
+ | Trap::Exception(Exception::InstructionPageFault)
+ | Trap::Exception(Exception::LoadFault)
+ | Trap::Exception(Exception::LoadPageFault) => {
println!(
"[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.",
- scause.cause(),
- stval,
- current_trap_cx().sepc,
+ scause.cause(),
+ stval,
+ current_trap_cx().sepc,
);
- // page fault exit code
- exit_current_and_run_next(-2);
+ // page fault exit code
+ exit_current_and_run_next(-2);
}
- Trap::Exception(Exception::IllegalInstruction) => {
+ Trap::Exception(Exception::IllegalInstruction) => {
println!("[kernel] IllegalInstruction in application, kernel killed it.");
- // illegal instruction exit code
- exit_current_and_run_next(-3);
+ // illegal instruction exit code
+ exit_current_and_run_next(-3);
}
- Trap::Interrupt(Interrupt::SupervisorTimer) => {
- set_next_trigger();
- suspend_current_and_run_next();
+ Trap::Interrupt(Interrupt::SupervisorTimer) => {
+ set_next_trigger();
+ suspend_current_and_run_next();
}
- _ => {
+ _ => {
panic!(
"Unsupported trap {:?}, stval = {:#x}!",
- scause.cause(),
- stval
+ scause.cause(),
+ stval
);
}
}
- trap_return();
+ trap_return();
}
-#[no_mangle]
-/// set the new addr of __restore asm function in TRAMPOLINE page,
-/// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
-/// finally, jump to new addr of __restore asm function
-pub fn trap_return() -> ! {
- set_user_trap_entry();
- let trap_cx_ptr = TRAP_CONTEXT;
- let user_satp = current_user_token();
- extern "C" {
- fn __alltraps();
- fn __restore();
+#[no_mangle]
+/// set the new addr of __restore asm function in TRAMPOLINE page,
+/// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
+/// finally, jump to new addr of __restore asm function
+pub fn trap_return() -> ! {
+ set_user_trap_entry();
+ let trap_cx_ptr = TRAP_CONTEXT;
+ let user_satp = current_user_token();
+ extern "C" {
+ fn __alltraps();
+ fn __restore();
}
- let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
- unsafe {
+ let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
+ unsafe {
asm!(
"fence.i",
"jr {restore_va}",
- restore_va = in(reg) restore_va,
- in("a0") trap_cx_ptr,
- in("a1") user_satp,
- options(noreturn)
+ restore_va = in(reg) restore_va,
+ in("a0") trap_cx_ptr,
+ in("a1") user_satp,
+ options(noreturn)
);
}
}
-#[no_mangle]
-/// Unimplement: traps/interrupts/exceptions from kernel mode
-/// Todo: Chapter 9: I/O device
-pub fn trap_from_kernel() -> ! {
- panic!("a trap {:?} from kernel!", scause::read().cause());
+#[no_mangle]
+/// Unimplement: traps/interrupts/exceptions from kernel mode
+/// Todo: Chapter 9: I/O device
+pub fn trap_from_kernel() -> ! {
+ panic!("a trap {:?} from kernel!", scause::read().cause());
}
-pub use context::TrapContext;
-
-
\ No newline at end of file
+pub use context::TrapContext;
+
\ No newline at end of file
diff --git a/ch5/COPYRIGHT.txt b/ch5/static.files/COPYRIGHT-23e9bde6c69aea69.txt
similarity index 97%
rename from ch5/COPYRIGHT.txt
rename to ch5/static.files/COPYRIGHT-23e9bde6c69aea69.txt
index 34e48134..1447df79 100644
--- a/ch5/COPYRIGHT.txt
+++ b/ch5/static.files/COPYRIGHT-23e9bde6c69aea69.txt
@@ -1,3 +1,5 @@
+# REUSE-IgnoreStart
+
These documentation pages include resources by third parties. This copyright
file applies only to those resources. The following third party resources are
included, and carry their own copyright notices and license terms:
@@ -44,3 +46,5 @@ included, and carry their own copyright notices and license terms:
See SourceSerif4-LICENSE.md.
This copyright file is intended to be distributed with rustdoc output.
+
+# REUSE-IgnoreEnd
diff --git a/ch5/FiraSans-LICENSE.txt b/ch5/static.files/FiraSans-LICENSE-db4b642586e02d97.txt
similarity index 99%
rename from ch5/FiraSans-LICENSE.txt
rename to ch5/static.files/FiraSans-LICENSE-db4b642586e02d97.txt
index ff9afab0..d7e9c149 100644
--- a/ch5/FiraSans-LICENSE.txt
+++ b/ch5/static.files/FiraSans-LICENSE-db4b642586e02d97.txt
@@ -1,3 +1,5 @@
+// REUSE-IgnoreStart
+
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
with Reserved Font Name < Fira >,
@@ -92,3 +94,5 @@ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+
+// REUSE-IgnoreEnd
diff --git a/ch5/FiraSans-Medium.woff2 b/ch5/static.files/FiraSans-Medium-8f9a781e4970d388.woff2
similarity index 100%
rename from ch5/FiraSans-Medium.woff2
rename to ch5/static.files/FiraSans-Medium-8f9a781e4970d388.woff2
diff --git a/ch5/FiraSans-Regular.woff2 b/ch5/static.files/FiraSans-Regular-018c141bf0843ffd.woff2
similarity index 100%
rename from ch5/FiraSans-Regular.woff2
rename to ch5/static.files/FiraSans-Regular-018c141bf0843ffd.woff2
diff --git a/ch5/LICENSE-APACHE.txt b/ch5/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt
similarity index 100%
rename from ch5/LICENSE-APACHE.txt
rename to ch5/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt
diff --git a/ch5/LICENSE-MIT.txt b/ch5/static.files/LICENSE-MIT-65090b722b3f6c56.txt
similarity index 100%
rename from ch5/LICENSE-MIT.txt
rename to ch5/static.files/LICENSE-MIT-65090b722b3f6c56.txt
diff --git a/ch5/NanumBarunGothic.ttf.woff2 b/ch5/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2
similarity index 100%
rename from ch5/NanumBarunGothic.ttf.woff2
rename to ch5/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2
diff --git a/ch5/NanumBarunGothic-LICENSE.txt b/ch5/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt
similarity index 99%
rename from ch5/NanumBarunGothic-LICENSE.txt
rename to ch5/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt
index 0bf46682..4b3edc29 100644
--- a/ch5/NanumBarunGothic-LICENSE.txt
+++ b/ch5/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt
@@ -1,3 +1,5 @@
+// REUSE-IgnoreStart
+
Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/),
with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic,
@@ -97,3 +99,5 @@ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+
+// REUSE-IgnoreEnd
diff --git a/ch5/SourceCodePro-It.ttf.woff2 b/ch5/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2
similarity index 100%
rename from ch5/SourceCodePro-It.ttf.woff2
rename to ch5/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2
diff --git a/ch5/SourceCodePro-LICENSE.txt b/ch5/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt
similarity index 99%
rename from ch5/SourceCodePro-LICENSE.txt
rename to ch5/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt
index 07542572..0d2941e1 100644
--- a/ch5/SourceCodePro-LICENSE.txt
+++ b/ch5/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt
@@ -1,3 +1,5 @@
+// REUSE-IgnoreStart
+
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
@@ -91,3 +93,5 @@ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+
+// REUSE-IgnoreEnd
diff --git a/ch5/SourceCodePro-Regular.ttf.woff2 b/ch5/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2
similarity index 100%
rename from ch5/SourceCodePro-Regular.ttf.woff2
rename to ch5/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2
diff --git a/ch5/SourceCodePro-Semibold.ttf.woff2 b/ch5/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2
similarity index 100%
rename from ch5/SourceCodePro-Semibold.ttf.woff2
rename to ch5/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2
diff --git a/ch5/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/ch5/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2
new file mode 100644
index 00000000..181a07f6
Binary files /dev/null and b/ch5/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ
diff --git a/ch5/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/ch5/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2
new file mode 100644
index 00000000..2ae08a7b
Binary files /dev/null and b/ch5/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ
diff --git a/ch5/SourceSerif4-LICENSE.md b/ch5/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md
similarity index 94%
rename from ch5/SourceSerif4-LICENSE.md
rename to ch5/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md
index 68ea1892..175fa4f4 100644
--- a/ch5/SourceSerif4-LICENSE.md
+++ b/ch5/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md
@@ -1,4 +1,7 @@
+
+
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
+Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
@@ -91,3 +94,5 @@ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
diff --git a/ch5/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/ch5/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2
new file mode 100644
index 00000000..0263fc30
Binary files /dev/null and b/ch5/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ
diff --git a/ch5/clipboard.svg b/ch5/static.files/clipboard-7571035ce49a181d.svg
similarity index 100%
rename from ch5/clipboard.svg
rename to ch5/static.files/clipboard-7571035ce49a181d.svg
diff --git a/ch5/favicon-16x16.png b/ch5/static.files/favicon-16x16-8b506e7a72182f1c.png
similarity index 100%
rename from ch5/favicon-16x16.png
rename to ch5/static.files/favicon-16x16-8b506e7a72182f1c.png
diff --git a/ch5/favicon.svg b/ch5/static.files/favicon-2c020d218678b618.svg
similarity index 100%
rename from ch5/favicon.svg
rename to ch5/static.files/favicon-2c020d218678b618.svg
diff --git a/ch5/favicon-32x32.png b/ch5/static.files/favicon-32x32-422f7d1d52889060.png
similarity index 100%
rename from ch5/favicon-32x32.png
rename to ch5/static.files/favicon-32x32-422f7d1d52889060.png
diff --git a/ch5/static.files/main-c5bd66d33317d69f.js b/ch5/static.files/main-c5bd66d33317d69f.js
new file mode 100644
index 00000000..43133d66
--- /dev/null
+++ b/ch5/static.files/main-c5bd66d33317d69f.js
@@ -0,0 +1,12 @@
+"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar&&locationTitle){const mobileTitle=document.createElement("h2");mobileTitle.innerHTML=locationTitle.innerHTML;mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML=""+searchState.loadingText+"
";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML=""+window.NOTABLE_TRAITS[notable_ty]+""}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \
+the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>""+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+" "+x[1]+" ").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="Keyboard Shortcuts
"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="Search Tricks
"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}())
\ No newline at end of file
diff --git a/ch5/normalize.css b/ch5/static.files/normalize-76eba96aa4d2e634.css
similarity index 100%
rename from ch5/normalize.css
rename to ch5/static.files/normalize-76eba96aa4d2e634.css
diff --git a/ch5/static.files/noscript-5d8b3c7633ad77ba.css b/ch5/static.files/noscript-5d8b3c7633ad77ba.css
new file mode 100644
index 00000000..8c63ef06
--- /dev/null
+++ b/ch5/static.files/noscript-5d8b3c7633ad77ba.css
@@ -0,0 +1 @@
+ #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}}
\ No newline at end of file
diff --git a/ch5/rust-logo.svg b/ch5/static.files/rust-logo-151179464ae7ed46.svg
similarity index 100%
rename from ch5/rust-logo.svg
rename to ch5/static.files/rust-logo-151179464ae7ed46.svg
diff --git a/ch5/static.files/rustdoc-fa3bb1812debf86c.css b/ch5/static.files/rustdoc-fa3bb1812debf86c.css
new file mode 100644
index 00000000..2dd5cebc
--- /dev/null
+++ b/ch5/static.files/rustdoc-fa3bb1812debf86c.css
@@ -0,0 +1,10 @@
+ :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml,');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a,:root[data-theme="ayu"] #source-sidebar>.title{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img{filter:invert(100);}
\ No newline at end of file
diff --git a/ch5/static.files/scrape-examples-ef1e698c1d417c0c.js b/ch5/static.files/scrape-examples-ef1e698c1d417c0c.js
new file mode 100644
index 00000000..ba830e37
--- /dev/null
+++ b/ch5/static.files/scrape-examples-ef1e698c1d417c0c.js
@@ -0,0 +1 @@
+"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})()
\ No newline at end of file
diff --git a/ch5/static.files/search-5f5ec5419eadd0c9.js b/ch5/static.files/search-5f5ec5419eadd0c9.js
new file mode 100644
index 00000000..e25c1820
--- /dev/null
+++ b/ch5/static.files/search-5f5ec5419eadd0c9.js
@@ -0,0 +1,5 @@
+"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias","generic",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem,whereClause,mgensInout){return unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgensInout,mgens=>{if(mgensInout){for(const[fid,qid]of mgens.entries()){mgensInout.set(fid,qid)}}return true})}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){let mgens=new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;let fl=fnTypesIn.length;let fnTypes=fnTypesIn.slice();const backtracking=[];let i=0;let j=0;const backtrack=()=>{while(backtracking.length!==0){const{fnTypesScratch,mgensScratch,queryElemsOffset,fnTypesOffset,unbox,}=backtracking.pop();mgens=new Map(mgensScratch);const fnType=fnTypesScratch[fnTypesOffset];const queryElem=queryElems[queryElemsOffset];if(unbox){if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}mgens.set(fnType.id,0)}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;fnTypes=fnTypesScratch.toSpliced(fnTypesOffset,1,...generics);fl=fnTypes.length;i=queryElemsOffset-1}else{if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}mgens.set(fnType.id,queryElem.id)}fnTypes=fnTypesScratch.slice();fl=fnTypes.length;const tmp=fnTypes[queryElemsOffset];fnTypes[queryElemsOffset]=fnTypes[fnTypesOffset];fnTypes[fnTypesOffset]=tmp;i=queryElemsOffset}return true}return false};for(i=0;i!==ql;++i){const queryElem=queryElems[i];const matchCandidates=[];let fnTypesScratch=null;let mgensScratch=null;for(j=i;j!==fl;++j){const fnType=fnTypes[j];if(unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgens,mgensScratch=>{matchCandidates.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:false,});return false})}if(unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}if(!mgensScratch){mgensScratch=new Map(mgens)}backtracking.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:true,})}}if(matchCandidates.length===0){if(backtrack()){continue}else{return false}}const{fnTypesOffset:candidate,mgensScratch:mgensNew}=matchCandidates.pop();if(fnTypes[candidate].id<0&&queryElems[i].id<0){mgens.set(fnTypes[candidate].id,queryElems[i].id)}for(const[fid,qid]of mgensNew){mgens.set(fid,qid)}const tmp=fnTypes[candidate];fnTypes[candidate]=fnTypes[i];fnTypes[i]=tmp;for(const otherCandidate of matchCandidates){backtracking.push(otherCandidate)}while(i===(ql-1)&&solutionCb&&!solutionCb(mgens)){if(!backtrack()){return false}}}return true}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgens.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(fnType.id!==queryElem.id){return false}if(fnType.generics.length===0&&queryElem.generics.length!==0){return false}const queryElemPathLength=queryElem.pathWithoutLast.length;if(queryElemPathLength>0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i=0){if(!whereClause){return false}if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause)}else if(fnType.generics&&fnType.generics.length>0){return checkIfInList(fnType.generics,queryElem,whereClause)}return false}function checkIfInList(list,elem,whereClause){for(const entry of list){if(checkType(entry,elem,whereClause)){return true}}return false}function checkType(row,elem,whereClause){if(row.id===null){return row.generics.length>0?checkIfInList(row.generics,elem,whereClause):false}if(row.id<0&&elem.id>=0){const gid=(-row.id)-1;return checkIfInList(whereClause[gid],elem,whereClause)}if(row.id<0&&elem.id<0){return true}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem,whereClause,new Map())}return true}return checkIfInList(row.generics,elem,whereClause)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem){if(typeNameIdMap.has(elem.pathLast)){elem.id=typeNameIdMap.get(elem.pathLast)}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.pathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=` \
+${item.alias} - see \
+`}resultName.insertAdjacentHTML("beforeend",`${alias}\
+${item.displayPath}${name}\
+`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?
"+"Or try looking in one of these:- The Rust Reference "+" for technical details about the language.
- Rust By "+"Example for expository code examples.
- The Rust Book for "+"introductions to language features and the language itself.
- Docs.rs for documentation of crates released on"+" crates.io.
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in "}let output=`Results${crates}
`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`Query parser error: "${error.join("")}".
`;output+=""+makeTabHeader(0,"In Names",ret_others[1])+"";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+=""+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+""}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+=""+makeTabHeader(0,signatureTabTitle,ret_others[1])+"";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+=""+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.
`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+=""+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.
`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.map(type=>buildItemSearchType(type,lowercasePaths))}function buildItemSearchType(type,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}if(pathIndex<0){return{id:pathIndex,ty:TY_GENERIC,path:null,generics,}}if(pathIndex===0){return{id:null,ty:null,path:null,generics,}}const item=lowercasePaths[pathIndex-1];return{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics,}}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})()
\ No newline at end of file
diff --git a/ch5/static.files/settings-74424d7eec62a23e.js b/ch5/static.files/settings-74424d7eec62a23e.js
new file mode 100644
index 00000000..3014f75c
--- /dev/null
+++ b/ch5/static.files/settings-74424d7eec62a23e.js
@@ -0,0 +1,17 @@
+"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\
+
+ ${setting_name}
+ `;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\
+ `});output+=`\
+
+`}else{const checked=setting["default"]===true?" checked":"";output+=`\
+\
+ \
+`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`${buildSettingsPageSections(settings)}`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})()
\ No newline at end of file
diff --git a/ch5/static.files/src-script-3280b574d94e47b4.js b/ch5/static.files/src-script-3280b574d94e47b4.js
new file mode 100644
index 00000000..9ea88921
--- /dev/null
+++ b/ch5/static.files/src-script-3280b574d94e47b4.js
@@ -0,0 +1 @@
+"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})()
\ No newline at end of file
diff --git a/ch5/static.files/storage-fec3eaa3851e447d.js b/ch5/static.files/storage-fec3eaa3851e447d.js
new file mode 100644
index 00000000..a687118f
--- /dev/null
+++ b/ch5/static.files/storage-fec3eaa3851e447d.js
@@ -0,0 +1 @@
+"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}})
\ No newline at end of file
diff --git a/ch5/static.files/wheel-7b819b6101059cd0.svg b/ch5/static.files/wheel-7b819b6101059cd0.svg
new file mode 100644
index 00000000..83c07f63
--- /dev/null
+++ b/ch5/static.files/wheel-7b819b6101059cd0.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ch5/storage.js b/ch5/storage.js
deleted file mode 100644
index 07f8962f..00000000
--- a/ch5/storage.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");window.mainTheme=document.getElementById("mainThemeStyle");window.RUSTDOC_MOBILE_BREAKPOINT=701;const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}const dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current!==null){return current}if(settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return null}const localStoredTheme=getSettingValue("theme");const savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){if(reversed){const length=arr.length;for(let i=length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){const newHref=mainStyleElem.href.replace(/\/rustdoc([^/]*)\.css/,"/"+newTheme+"$1"+".css");if(saveTheme){updateLocalStorage("theme",newTheme)}if(styleElem.href===newHref){return}let found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),el=>{savedHref.push(el.href)})}onEach(savedHref,el=>{if(el===newHref){found=true;return true}});if(found){styleElem.href=newHref}}function useSystemTheme(value){if(value===undefined){value=true}updateLocalStorage("use-system-theme",value);const toggle=document.getElementById("use-system-theme");if(toggle&&toggle instanceof HTMLInputElement){toggle.checked=value}}const updateSystemTheme=(function(){if(!window.matchMedia){return()=>{const cssTheme=getComputedStyle(document.documentElement).getPropertyValue("content");switchTheme(window.currentTheme,window.mainTheme,JSON.parse(cssTheme)||"light",true)}}const mql=window.matchMedia("(prefers-color-scheme: dark)");function handlePreferenceChange(mql){const use=theme=>{switchTheme(window.currentTheme,window.mainTheme,theme,true)};if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";if(mql.matches){use(darkTheme)}else{use(lightTheme)}}else{use(getSettingValue("theme"))}}mql.addListener(handlePreferenceChange);return()=>{handlePreferenceChange(mql)}})();function switchToSavedTheme(){switchTheme(window.currentTheme,window.mainTheme,getSettingValue("theme")||"light",false)}if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchToSavedTheme()}if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"source-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(switchToSavedTheme,0)}})
\ No newline at end of file
diff --git a/ch5/toggle-minus.svg b/ch5/toggle-minus.svg
deleted file mode 100644
index 73154788..00000000
--- a/ch5/toggle-minus.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ch5/toggle-plus.svg b/ch5/toggle-plus.svg
deleted file mode 100644
index 08b17033..00000000
--- a/ch5/toggle-plus.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ch5/wheel.svg b/ch5/wheel.svg
deleted file mode 100644
index 01da3b24..00000000
--- a/ch5/wheel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file