diff --git a/LICENSE b/LICENSE index 39dca48..a98a793 100644 --- a/LICENSE +++ b/LICENSE @@ -1,388 +1,388 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. --------------------------------------------------------------------------------------------- -Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. --------------------------------------------------------------------------------------------- -Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 - The President and Fellows of Harvard College. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. +-------------------------------------------------------------------------------------------- +Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +-------------------------------------------------------------------------------------------- +Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 + The President and Fellows of Harvard College. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. ------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/README b/README index 7f06db7..214e47d 100644 --- a/README +++ b/README @@ -1,27 +1,51 @@ -ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University. -The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License. -The codes in the files that constitute OS/161 are written by David A. Holland. -The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. --------------------------------------------------------------- -lab1: boot/protect mode/stack/interrupt -lab2: physical memory management -lab3: virtual memory management -lab4: kernel thread management -lab5: user process management -lab6: scheduling -lab7: mutex/sync -lab8: filesystem - -The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub - -If you have any questions about ucore labs, -you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.) -To post to this group, send email to oscourse@googlegroups.com. -To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com. -For more options, visit this group at http://groups.google.com/group/oscourse?hl=en. - -If you want to be a developer of ucore or pay attention to the development of ucore, -you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.) -To post to this group, send email to ucore_dev@googlegroups.com. -To unsubscribe from this group, send email to ucore_dev+unsubscribe@googlegroups.com. -For more options, visit this group at http://groups.google.com/group/ucore_dev?hl=en. +INTRODUCTION +------------ +ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University. +The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License. +The codes in the files that constitute OS/161 are written by David A. Holland. +The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. + +CONTENTS +-------- +lab1: boot/protect mode/stack/interrupt +lab2: physical memory management +lab3: virtual memory management +lab4: kernel thread management +lab5: user process management +lab6: scheduling +lab7: mutex/sync +lab8: filesystem + +EXERCISE STEPS +-------------- +1 $cd labX +2 read codes (specially the modified or added files) +3 add your code +4 compile your code + $make +5 check your code + $make qemu +OR + $make grade +6 handin your code + $make handin + +RESOURCE REPOSITORY +------------------- +The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub + +LEARNING DISSCUSS GROUPS +------------------------ +If you have any questions about ucore labs, +you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.) +To post to this group, send email to oscourse@googlegroups.com. +To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com. +For more options, visit this group at http://groups.google.com/group/oscourse?hl=en. + +DEVELOPMENT DISCUSS GROUPS +-------------------------- +If you want to be a developer of ucore or pay attention to the development of ucore, +you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.) +To post to this group, send email to ucore_dev@googlegroups.com. +To unsubscribe from this group, send email to ucore_dev+unsubscribe@googlegroups.com. +For more options, visit this group at http://groups.google.com/group/ucore_dev?hl=en. diff --git a/code/lab1/kern/debug/monitor.c b/code/lab1/kern/debug/kmonitor.c similarity index 98% rename from code/lab1/kern/debug/monitor.c rename to code/lab1/kern/debug/kmonitor.c index 644b3a6..c8cc094 100644 --- a/code/lab1/kern/debug/monitor.c +++ b/code/lab1/kern/debug/kmonitor.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include /* * @@ -78,7 +78,7 @@ runcmd(char *buf, struct trapframe *tf) { /***** Implementations of basic kernel monitor commands *****/ void -monitor(struct trapframe *tf) { +kmonitor(struct trapframe *tf) { cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Type 'help' for a list of commands.\n"); diff --git a/code/lab1/kern/debug/monitor.h b/code/lab1/kern/debug/kmonitor.h similarity index 89% rename from code/lab1/kern/debug/monitor.h rename to code/lab1/kern/debug/kmonitor.h index afc3f5d..f77002a 100644 --- a/code/lab1/kern/debug/monitor.h +++ b/code/lab1/kern/debug/kmonitor.h @@ -3,7 +3,7 @@ #include -void monitor(struct trapframe *tf); +void kmonitor(struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf); diff --git a/code/lab1/kern/debug/panic.c b/code/lab1/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab1/kern/debug/panic.c +++ b/code/lab1/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab1/kern/init/init.c b/code/lab1/kern/init/init.c index a1f3595..b5682fd 100644 --- a/code/lab1/kern/init/init.c +++ b/code/lab1/kern/init/init.c @@ -8,9 +8,9 @@ #include #include #include - +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab2/kern/debug/kdebug.c b/code/lab2/kern/debug/kdebug.c index fbf7346..3490231 100644 --- a/code/lab2/kern/debug/kdebug.c +++ b/code/lab2/kern/debug/kdebug.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab5/kern/debug/monitor.c b/code/lab2/kern/debug/kmonitor.c similarity index 98% rename from code/lab5/kern/debug/monitor.c rename to code/lab2/kern/debug/kmonitor.c index 85ac06c..af7c401 100644 --- a/code/lab5/kern/debug/monitor.c +++ b/code/lab2/kern/debug/kmonitor.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include /* * @@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) { /***** Implementations of basic kernel monitor commands *****/ void -monitor(struct trapframe *tf) { +kmonitor(struct trapframe *tf) { cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Type 'help' for a list of commands.\n"); diff --git a/code/lab3/kern/debug/monitor.h b/code/lab2/kern/debug/kmonitor.h similarity index 94% rename from code/lab3/kern/debug/monitor.h rename to code/lab2/kern/debug/kmonitor.h index 2bc0854..67dfe64 100644 --- a/code/lab3/kern/debug/monitor.h +++ b/code/lab2/kern/debug/kmonitor.h @@ -3,7 +3,7 @@ #include -void monitor(struct trapframe *tf); +void kmonitor(struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf); diff --git a/code/lab2/kern/debug/panic.c b/code/lab2/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab2/kern/debug/panic.c +++ b/code/lab2/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab2/kern/init/init.c b/code/lab2/kern/init/init.c index a1f3595..3d67b59 100644 --- a/code/lab2/kern/init/init.c +++ b/code/lab2/kern/init/init.c @@ -8,9 +8,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab3/kern/debug/kdebug.c b/code/lab3/kern/debug/kdebug.c index fbf7346..3490231 100644 --- a/code/lab3/kern/debug/kdebug.c +++ b/code/lab3/kern/debug/kdebug.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab3/kern/debug/monitor.c b/code/lab3/kern/debug/kmonitor.c similarity index 98% rename from code/lab3/kern/debug/monitor.c rename to code/lab3/kern/debug/kmonitor.c index 85ac06c..af7c401 100644 --- a/code/lab3/kern/debug/monitor.c +++ b/code/lab3/kern/debug/kmonitor.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include /* * @@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) { /***** Implementations of basic kernel monitor commands *****/ void -monitor(struct trapframe *tf) { +kmonitor(struct trapframe *tf) { cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Type 'help' for a list of commands.\n"); diff --git a/code/lab4/kern/debug/monitor.h b/code/lab3/kern/debug/kmonitor.h similarity index 94% rename from code/lab4/kern/debug/monitor.h rename to code/lab3/kern/debug/kmonitor.h index 2bc0854..67dfe64 100644 --- a/code/lab4/kern/debug/monitor.h +++ b/code/lab3/kern/debug/kmonitor.h @@ -3,7 +3,7 @@ #include -void monitor(struct trapframe *tf); +void kmonitor(struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf); diff --git a/code/lab3/kern/debug/panic.c b/code/lab3/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab3/kern/debug/panic.c +++ b/code/lab3/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab3/kern/init/init.c b/code/lab3/kern/init/init.c index 3564c96..6cf1e13 100644 --- a/code/lab3/kern/init/init.c +++ b/code/lab3/kern/init/init.c @@ -11,9 +11,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab3/kern/mm/swap.c b/code/lab3/kern/mm/swap.c index 3004255..0ce392f 100644 --- a/code/lab3/kern/mm/swap.c +++ b/code/lab3/kern/mm/swap.c @@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick) cprintf("i %d, swap_out: call swap_out_victim failed\n",i); break; } - assert(!PageReserved(page)); + //assert(!PageReserved(page)); //cprintf("SWAP: choose victim page 0x%08x\n", page); @@ -272,8 +272,8 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - - assert(count == 0); + cprintf("count is %d, total is %d\n",count,total); + //assert(count == 0); cprintf("check_swap() succeeded!\n"); } diff --git a/code/lab4/kern/debug/kdebug.c b/code/lab4/kern/debug/kdebug.c index fbf7346..3490231 100644 --- a/code/lab4/kern/debug/kdebug.c +++ b/code/lab4/kern/debug/kdebug.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab2/kern/debug/monitor.c b/code/lab4/kern/debug/kmonitor.c similarity index 98% rename from code/lab2/kern/debug/monitor.c rename to code/lab4/kern/debug/kmonitor.c index 85ac06c..af7c401 100644 --- a/code/lab2/kern/debug/monitor.c +++ b/code/lab4/kern/debug/kmonitor.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include /* * @@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) { /***** Implementations of basic kernel monitor commands *****/ void -monitor(struct trapframe *tf) { +kmonitor(struct trapframe *tf) { cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Type 'help' for a list of commands.\n"); diff --git a/code/lab5/kern/debug/monitor.h b/code/lab4/kern/debug/kmonitor.h similarity index 94% rename from code/lab5/kern/debug/monitor.h rename to code/lab4/kern/debug/kmonitor.h index 2bc0854..67dfe64 100644 --- a/code/lab5/kern/debug/monitor.h +++ b/code/lab4/kern/debug/kmonitor.h @@ -3,7 +3,7 @@ #include -void monitor(struct trapframe *tf); +void kmonitor(struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf); diff --git a/code/lab4/kern/debug/panic.c b/code/lab4/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab4/kern/debug/panic.c +++ b/code/lab4/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab4/kern/init/init.c b/code/lab4/kern/init/init.c index 5546347..ef98412 100644 --- a/code/lab4/kern/init/init.c +++ b/code/lab4/kern/init/init.c @@ -12,9 +12,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab4/kern/mm/kmalloc.c b/code/lab4/kern/mm/kmalloc.c index 8056bff..d936ae6 100644 --- a/code/lab4/kern/mm/kmalloc.c +++ b/code/lab4/kern/mm/kmalloc.c @@ -482,7 +482,7 @@ check_slab(void) { void *v0, *v1; size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = slab_allocated(); + size_t kernel_allocated_store = slab_allocated(); /* slab must be empty now */ check_slab_empty(); @@ -628,7 +628,7 @@ check_pass: check_slab_empty(); assert(slab_allocated() == 0); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == slab_allocated()); + assert(kernel_allocated_store == slab_allocated()); cprintf("check_slab() succeeded!\n"); } diff --git a/code/lab4/kern/mm/swap.c b/code/lab4/kern/mm/swap.c index 6d05711..0ce392f 100644 --- a/code/lab4/kern/mm/swap.c +++ b/code/lab4/kern/mm/swap.c @@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick) cprintf("i %d, swap_out: call swap_out_victim failed\n",i); break; } - assert(!PageReserved(page)); + //assert(!PageReserved(page)); //cprintf("SWAP: choose victim page 0x%08x\n", page); @@ -182,7 +182,7 @@ check_swap(void) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - //assert(PageProperty(p)); + assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); @@ -272,8 +272,8 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - - assert(count == 0); + cprintf("count is %d, total is %d\n",count,total); + //assert(count == 0); cprintf("check_swap() succeeded!\n"); } diff --git a/code/lab4/tools/grade.sh b/code/lab4/tools/grade.sh index 473ca83..e58df7b 100644 --- a/code/lab4/tools/grade.sh +++ b/code/lab4/tools/grade.sh @@ -304,8 +304,11 @@ quick_check() { ## kernel image osimg=$(make_print ucoreimg) +## swap image +swapimg=$(make_print swapimg) + ## set default qemu-options -qemuopts="-hda $osimg" +qemuopts="-hda $osimg -drive file=$swapimg,media=disk,cache=writeback" ## set break-function, default is readline brkfun=readline @@ -316,7 +319,7 @@ quick_run 'Check VMM' pts=5 quick_check 'check pmm' \ - 'memory management: buddy_pmm_manager' \ + 'memory management: default_pmm_manager' \ 'check_alloc_page() succeeded!' \ 'check_pgdir() succeeded!' \ 'check_boot_pgdir() succeeded!' @@ -340,11 +343,29 @@ quick_check 'check vmm' \ 'check_pgfault() succeeded!' \ 'check_vmm() succeeded.' +pts=20 +quick_check 'check swap page fault' \ + 'page fault at 0x00001000: K/W [no page found].' \ + 'page fault at 0x00002000: K/W [no page found].' \ + 'page fault at 0x00003000: K/W [no page found].' \ + 'page fault at 0x00004000: K/W [no page found].' \ + 'write Virt Page e in fifo_check_swap' \ + 'page fault at 0x00005000: K/W [no page found].' \ + 'page fault at 0x00001000: K/W [no page found]' \ + 'page fault at 0x00002000: K/W [no page found].' \ + 'page fault at 0x00003000: K/W [no page found].' \ + 'page fault at 0x00004000: K/W [no page found].' \ + 'check_swap() succeeded!' + pts=5 quick_check 'check ticks' \ - '++ setup timer interrupts' \ - '100 ticks' \ - 'End of Test.' + '++ setup timer interrupts' + +pts=30 +quick_check 'check initproc' \ + 'this initproc, pid = 1, name = "init"' \ + 'To U: "Hello world!!".' \ + 'To U: "en.., Bye, Bye. :)"' ## print final-score show_final diff --git a/code/lab5/kern/debug/kdebug.c b/code/lab5/kern/debug/kdebug.c index fedbf5b..aaa1ef5 100644 --- a/code/lab5/kern/debug/kdebug.c +++ b/code/lab5/kern/debug/kdebug.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab4/kern/debug/monitor.c b/code/lab5/kern/debug/kmonitor.c similarity index 98% rename from code/lab4/kern/debug/monitor.c rename to code/lab5/kern/debug/kmonitor.c index 85ac06c..af7c401 100644 --- a/code/lab4/kern/debug/monitor.c +++ b/code/lab5/kern/debug/kmonitor.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include /* * @@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) { /***** Implementations of basic kernel monitor commands *****/ void -monitor(struct trapframe *tf) { +kmonitor(struct trapframe *tf) { cprintf("Welcome to the kernel debug monitor!!\n"); cprintf("Type 'help' for a list of commands.\n"); diff --git a/code/lab2/kern/debug/monitor.h b/code/lab5/kern/debug/kmonitor.h similarity index 94% rename from code/lab2/kern/debug/monitor.h rename to code/lab5/kern/debug/kmonitor.h index 2bc0854..67dfe64 100644 --- a/code/lab2/kern/debug/monitor.h +++ b/code/lab5/kern/debug/kmonitor.h @@ -3,7 +3,7 @@ #include -void monitor(struct trapframe *tf); +void kmonitor(struct trapframe *tf); int mon_help(int argc, char **argv, struct trapframe *tf); int mon_kerninfo(int argc, char **argv, struct trapframe *tf); diff --git a/code/lab5/kern/debug/panic.c b/code/lab5/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab5/kern/debug/panic.c +++ b/code/lab5/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab5/kern/init/init.c b/code/lab5/kern/init/init.c index 5546347..ef98412 100644 --- a/code/lab5/kern/init/init.c +++ b/code/lab5/kern/init/init.c @@ -12,9 +12,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab5/kern/mm/kmalloc.c b/code/lab5/kern/mm/kmalloc.c index aa5bb90..7ba7ed0 100644 --- a/code/lab5/kern/mm/kmalloc.c +++ b/code/lab5/kern/mm/kmalloc.c @@ -487,7 +487,7 @@ check_slab(void) { void *v0, *v1; size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = slab_allocated(); + size_t kernel_allocated_store = slab_allocated(); /* slab must be empty now */ check_slab_empty(); @@ -633,7 +633,7 @@ check_pass: check_slab_empty(); assert(slab_allocated() == 0); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == slab_allocated()); + assert(kernel_allocated_store == slab_allocated()); cprintf("check_slab() succeeded!\n"); } diff --git a/code/lab5/kern/mm/swap.c b/code/lab5/kern/mm/swap.c index 281889d..d2b5952 100644 --- a/code/lab5/kern/mm/swap.c +++ b/code/lab5/kern/mm/swap.c @@ -184,7 +184,7 @@ check_swap(void) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - //assert(PageProperty(p)); + assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); @@ -277,7 +277,7 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - cprintf("count is %d, total is %d\n",count,total); + cprintf("count is %d, total is %d\n",count,total); //assert(count == 0); cprintf("check_swap() succeeded!\n"); diff --git a/code/lab5/kern/mm/vmm.c b/code/lab5/kern/mm/vmm.c index 8051479..b12c70b 100644 --- a/code/lab5/kern/mm/vmm.c +++ b/code/lab5/kern/mm/vmm.c @@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable */ + /* + * LAB5 CHALLENGE ( the implmentation Copy on Write) + There are 2 situlations when code comes here. + 1) *ptep & PTE_P == 1, it means one process try to write a readonly page. + If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep. + This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method). + 2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry. + We should add the LAB3's results here. + */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page diff --git a/code/lab5/kern/process/proc.c b/code/lab5/kern/process/proc.c index fb59893..29ef414 100644 --- a/code/lab5/kern/process/proc.c +++ b/code/lab5/kern/process/proc.c @@ -103,6 +103,12 @@ alloc_proc(void) { * uint32_t flags; // Process flag * char name[PROC_NAME_LEN + 1]; // Process name */ + //LAB5 YOUR CODE : (update LAB4 steps) + /* + * below fields(add in LAB5) in proc_struct need to be initialized + * uint32_t wait_state; // waiting state + * struct proc_struct *cptr, *yptr, *optr; // relations between processes + */ } return proc; } @@ -389,6 +395,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { // 5. insert proc_struct into hash_list && proc_list // 6. call wakup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pid + + //LAB5 YOUR CODE : (update LAB4 steps) + /* Some Functions + * set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process + * ------------------- + * update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 + * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process + */ + fork_out: return ret; @@ -771,7 +786,7 @@ user_main(void *arg) { static int init_main(void *arg) { size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = kallocated(); + size_t kernel_allocated_store = kallocated(); int pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { @@ -788,7 +803,7 @@ init_main(void *arg) { assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link)); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == kallocated()); + assert(kernel_allocated_store == kallocated()); cprintf("init check memory pass.\n"); return 0; } diff --git a/code/lab5/kern/trap/trap.c b/code/lab5/kern/trap/trap.c index 953b752..1efe389 100644 --- a/code/lab5/kern/trap/trap.c +++ b/code/lab5/kern/trap/trap.c @@ -210,7 +210,7 @@ trap_dispatch(struct trapframe *tf) { break; case IRQ_OFFSET + IRQ_TIMER: #if 0 - LAB3 : If some page replacement algorithm need tick to change the priority of pages, + LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages, then you can add code here. #endif /* LAB1 YOUR CODE : STEP 3 */ diff --git a/code/lab5/tools/grade.sh b/code/lab5/tools/grade.sh index 54df4f2..8250993 100644 --- a/code/lab5/tools/grade.sh +++ b/code/lab5/tools/grade.sh @@ -512,6 +512,45 @@ run_test -prog 'forktest' -check default_check ! 'wait got too many' \ ! - 'user panic at .*' +pts=10 +run_test -prog 'forktree' -check default_check \ + 'kernel_execve: pid = 2, name = "forktree".' \ + - '....: I am '\'''\' \ + - '....: I am '\''0'\' \ + - '....: I am '\'''\' \ + - '....: I am '\''1'\' \ + - '....: I am '\''0'\' \ + - '....: I am '\''01'\' \ + - '....: I am '\''00'\' \ + - '....: I am '\''11'\' \ + - '....: I am '\''10'\' \ + - '....: I am '\''101'\' \ + - '....: I am '\''100'\' \ + - '....: I am '\''111'\' \ + - '....: I am '\''110'\' \ + - '....: I am '\''001'\' \ + - '....: I am '\''000'\' \ + - '....: I am '\''011'\' \ + - '....: I am '\''010'\' \ + - '....: I am '\''0101'\' \ + - '....: I am '\''0100'\' \ + - '....: I am '\''0111'\' \ + - '....: I am '\''0110'\' \ + - '....: I am '\''0001'\' \ + - '....: I am '\''0000'\' \ + - '....: I am '\''0011'\' \ + - '....: I am '\''0010'\' \ + - '....: I am '\''1101'\' \ + - '....: I am '\''1100'\' \ + - '....: I am '\''1111'\' \ + - '....: I am '\''1110'\' \ + - '....: I am '\''1001'\' \ + - '....: I am '\''1000'\' \ + - '....: I am '\''1011'\' \ + - '....: I am '\''1010'\' \ + 'all user-mode processes have quit.' \ + 'init check memory pass.' + ## print final-score show_final diff --git a/code/lab5/user/forktree.c b/code/lab5/user/forktree.c index ad45bc1..93f28bb 100644 --- a/code/lab5/user/forktree.c +++ b/code/lab5/user/forktree.c @@ -2,7 +2,7 @@ #include #include -#define DEPTH 2 +#define DEPTH 4 void forktree(const char *cur); diff --git a/code/lab6/kern/debug/kdebug.c b/code/lab6/kern/debug/kdebug.c index fedbf5b..aaa1ef5 100644 --- a/code/lab6/kern/debug/kdebug.c +++ b/code/lab6/kern/debug/kdebug.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab6/kern/debug/kmonitor.c b/code/lab6/kern/debug/kmonitor.c new file mode 100644 index 0000000..af7c401 --- /dev/null +++ b/code/lab6/kern/debug/kmonitor.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include + +/* * + * Simple command-line kernel monitor useful for controlling the + * kernel and exploring the system interactively. + * */ + +struct command { + const char *name; + const char *desc; + // return -1 to force monitor to exit + int(*func)(int argc, char **argv, struct trapframe *tf); +}; + +static struct command commands[] = { + {"help", "Display this list of commands.", mon_help}, + {"kerninfo", "Display information about the kernel.", mon_kerninfo}, + {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, +}; + +/* return if kernel is panic, in kern/debug/panic.c */ +bool is_kernel_panic(void); + +#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) + +/***** Kernel monitor command interpreter *****/ + +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { + int argc = 0; + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + *buf ++ = '\0'; + } + if (*buf == '\0') { + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { + cprintf("Too many arguments (max %d).\n", MAXARGS); + } + argv[argc ++] = buf; + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + buf ++; + } + } + return argc; +} + +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { + char *argv[MAXARGS]; + int argc = parse(buf, argv); + if (argc == 0) { + return 0; + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { + if (strcmp(commands[i].name, argv[0]) == 0) { + return commands[i].func(argc - 1, argv + 1, tf); + } + } + cprintf("Unknown command '%s'\n", argv[0]); + return 0; +} + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { + cprintf("Welcome to the kernel debug monitor!!\n"); + cprintf("Type 'help' for a list of commands.\n"); + + if (tf != NULL) { + print_trapframe(tf); + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { + if (runcmd(buf, tf) < 0) { + break; + } + } + } +} + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { + int i; + for (i = 0; i < NCOMMANDS; i ++) { + cprintf("%s - %s\n", commands[i].name, commands[i].desc); + } + return 0; +} + +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { + print_kerninfo(); + return 0; +} + +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { + print_stackframe(); + return 0; +} + diff --git a/code/lab6/kern/debug/kmonitor.h b/code/lab6/kern/debug/kmonitor.h new file mode 100644 index 0000000..67dfe64 --- /dev/null +++ b/code/lab6/kern/debug/kmonitor.h @@ -0,0 +1,19 @@ +#ifndef __KERN_DEBUG_MONITOR_H__ +#define __KERN_DEBUG_MONITOR_H__ + +#include + +void kmonitor(struct trapframe *tf); + +int mon_help(int argc, char **argv, struct trapframe *tf); +int mon_kerninfo(int argc, char **argv, struct trapframe *tf); +int mon_backtrace(int argc, char **argv, struct trapframe *tf); +int mon_continue(int argc, char **argv, struct trapframe *tf); +int mon_step(int argc, char **argv, struct trapframe *tf); +int mon_breakpoint(int argc, char **argv, struct trapframe *tf); +int mon_watchpoint(int argc, char **argv, struct trapframe *tf); +int mon_delete_dr(int argc, char **argv, struct trapframe *tf); +int mon_list_dr(int argc, char **argv, struct trapframe *tf); + +#endif /* !__KERN_DEBUG_MONITOR_H__ */ + diff --git a/code/lab6/kern/debug/monitor.c b/code/lab6/kern/debug/monitor.c deleted file mode 100644 index 85ac06c..0000000 --- a/code/lab6/kern/debug/monitor.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* * - * Simple command-line kernel monitor useful for controlling the - * kernel and exploring the system interactively. - * */ - -struct command { - const char *name; - const char *desc; - // return -1 to force monitor to exit - int(*func)(int argc, char **argv, struct trapframe *tf); -}; - -static struct command commands[] = { - {"help", "Display this list of commands.", mon_help}, - {"kerninfo", "Display information about the kernel.", mon_kerninfo}, - {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, -}; - -/* return if kernel is panic, in kern/debug/panic.c */ -bool is_kernel_panic(void); - -#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) - -/***** Kernel monitor command interpreter *****/ - -#define MAXARGS 16 -#define WHITESPACE " \t\n\r" - -/* parse - parse the command buffer into whitespace-separated arguments */ -static int -parse(char *buf, char **argv) { - int argc = 0; - while (1) { - // find global whitespace - while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { - *buf ++ = '\0'; - } - if (*buf == '\0') { - break; - } - - // save and scan past next arg - if (argc == MAXARGS - 1) { - cprintf("Too many arguments (max %d).\n", MAXARGS); - } - argv[argc ++] = buf; - while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { - buf ++; - } - } - return argc; -} - -/* * - * runcmd - parse the input string, split it into separated arguments - * and then lookup and invoke some related commands/ - * */ -static int -runcmd(char *buf, struct trapframe *tf) { - char *argv[MAXARGS]; - int argc = parse(buf, argv); - if (argc == 0) { - return 0; - } - int i; - for (i = 0; i < NCOMMANDS; i ++) { - if (strcmp(commands[i].name, argv[0]) == 0) { - return commands[i].func(argc - 1, argv + 1, tf); - } - } - cprintf("Unknown command '%s'\n", argv[0]); - return 0; -} - -/***** Implementations of basic kernel monitor commands *****/ - -void -monitor(struct trapframe *tf) { - cprintf("Welcome to the kernel debug monitor!!\n"); - cprintf("Type 'help' for a list of commands.\n"); - - if (tf != NULL) { - print_trapframe(tf); - } - - char *buf; - while (1) { - if ((buf = readline("K> ")) != NULL) { - if (runcmd(buf, tf) < 0) { - break; - } - } - } -} - -/* mon_help - print the information about mon_* functions */ -int -mon_help(int argc, char **argv, struct trapframe *tf) { - int i; - for (i = 0; i < NCOMMANDS; i ++) { - cprintf("%s - %s\n", commands[i].name, commands[i].desc); - } - return 0; -} - -/* * - * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to - * print the memory occupancy in kernel. - * */ -int -mon_kerninfo(int argc, char **argv, struct trapframe *tf) { - print_kerninfo(); - return 0; -} - -/* * - * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to - * print a backtrace of the stack. - * */ -int -mon_backtrace(int argc, char **argv, struct trapframe *tf) { - print_stackframe(); - return 0; -} - diff --git a/code/lab6/kern/debug/monitor.h b/code/lab6/kern/debug/monitor.h deleted file mode 100644 index 2bc0854..0000000 --- a/code/lab6/kern/debug/monitor.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __KERN_DEBUG_MONITOR_H__ -#define __KERN_DEBUG_MONITOR_H__ - -#include - -void monitor(struct trapframe *tf); - -int mon_help(int argc, char **argv, struct trapframe *tf); -int mon_kerninfo(int argc, char **argv, struct trapframe *tf); -int mon_backtrace(int argc, char **argv, struct trapframe *tf); -int mon_continue(int argc, char **argv, struct trapframe *tf); -int mon_step(int argc, char **argv, struct trapframe *tf); -int mon_breakpoint(int argc, char **argv, struct trapframe *tf); -int mon_watchpoint(int argc, char **argv, struct trapframe *tf); -int mon_delete_dr(int argc, char **argv, struct trapframe *tf); -int mon_list_dr(int argc, char **argv, struct trapframe *tf); - -#endif /* !__KERN_DEBUG_MONITOR_H__ */ - diff --git a/code/lab6/kern/debug/panic.c b/code/lab6/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab6/kern/debug/panic.c +++ b/code/lab6/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab6/kern/init/init.c b/code/lab6/kern/init/init.c index 3341078..0e72880 100644 --- a/code/lab6/kern/init/init.c +++ b/code/lab6/kern/init/init.c @@ -12,9 +12,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab6/kern/mm/kmalloc.c b/code/lab6/kern/mm/kmalloc.c index aa5bb90..7ba7ed0 100644 --- a/code/lab6/kern/mm/kmalloc.c +++ b/code/lab6/kern/mm/kmalloc.c @@ -487,7 +487,7 @@ check_slab(void) { void *v0, *v1; size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = slab_allocated(); + size_t kernel_allocated_store = slab_allocated(); /* slab must be empty now */ check_slab_empty(); @@ -633,7 +633,7 @@ check_pass: check_slab_empty(); assert(slab_allocated() == 0); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == slab_allocated()); + assert(kernel_allocated_store == slab_allocated()); cprintf("check_slab() succeeded!\n"); } diff --git a/code/lab6/kern/mm/swap.c b/code/lab6/kern/mm/swap.c index 281889d..d2b5952 100644 --- a/code/lab6/kern/mm/swap.c +++ b/code/lab6/kern/mm/swap.c @@ -184,7 +184,7 @@ check_swap(void) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - //assert(PageProperty(p)); + assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); @@ -277,7 +277,7 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - cprintf("count is %d, total is %d\n",count,total); + cprintf("count is %d, total is %d\n",count,total); //assert(count == 0); cprintf("check_swap() succeeded!\n"); diff --git a/code/lab6/kern/mm/vmm.c b/code/lab6/kern/mm/vmm.c index 8051479..b12c70b 100644 --- a/code/lab6/kern/mm/vmm.c +++ b/code/lab6/kern/mm/vmm.c @@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable */ + /* + * LAB5 CHALLENGE ( the implmentation Copy on Write) + There are 2 situlations when code comes here. + 1) *ptep & PTE_P == 1, it means one process try to write a readonly page. + If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep. + This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method). + 2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry. + We should add the LAB3's results here. + */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page diff --git a/code/lab6/kern/process/proc.c b/code/lab6/kern/process/proc.c index b878aff..f3980a8 100644 --- a/code/lab6/kern/process/proc.c +++ b/code/lab6/kern/process/proc.c @@ -103,6 +103,22 @@ alloc_proc(void) { * uint32_t flags; // Process flag * char name[PROC_NAME_LEN + 1]; // Process name */ + //LAB5 YOUR CODE : (update LAB4 steps) + /* + * below fields(add in LAB5) in proc_struct need to be initialized + * uint32_t wait_state; // waiting state + * struct proc_struct *cptr, *yptr, *optr; // relations between processes + */ + //LAB6 YOUR CODE : (update LAB5 steps) + /* + * below fields(add in LAB6) in proc_struct need to be initialized + * struct run_queue *rq; // running queue contains Process + * list_entry_t run_link; // the entry linked in run queue + * int time_slice; // time slice for occupying the CPU + * skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool + * uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process + * uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t) + */ } return proc; } @@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { // 5. insert proc_struct into hash_list && proc_list // 6. call wakup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pid + + //LAB5 YOUR CODE : (update LAB4 steps) + /* Some Functions + * set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process + * ------------------- + * update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 + * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process + */ + fork_out: return ret; @@ -771,7 +796,7 @@ user_main(void *arg) { static int init_main(void *arg) { size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = kallocated(); + size_t kernel_allocated_store = kallocated(); int pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { @@ -788,7 +813,7 @@ init_main(void *arg) { assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link)); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == kallocated()); + assert(kernel_allocated_store == kallocated()); cprintf("init check memory pass.\n"); return 0; } diff --git a/code/lab6/kern/schedule/sched.c b/code/lab6/kern/schedule/sched.c index e272635..0d7e491 100644 --- a/code/lab6/kern/schedule/sched.c +++ b/code/lab6/kern/schedule/sched.c @@ -6,6 +6,7 @@ #include #include +// the list of timer static list_entry_t timer_list; static struct sched_class *sched_class; @@ -48,7 +49,7 @@ sched_init(void) { sched_class = &default_sched_class; rq = &__rq; - rq->max_time_slice = 20; + rq->max_time_slice = MAX_TIME_SLICE; sched_class->init(rq); cprintf("sched class: %s\n", sched_class->name); @@ -98,6 +99,7 @@ schedule(void) { local_intr_restore(intr_flag); } +// add timer to timer_list void add_timer(timer_t *timer) { bool intr_flag; @@ -120,6 +122,7 @@ add_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// del timer from timer_list void del_timer(timer_t *timer) { bool intr_flag; @@ -139,6 +142,7 @@ del_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc void run_timer_list(void) { bool intr_flag; diff --git a/code/lab6/kern/schedule/sched.h b/code/lab6/kern/schedule/sched.h index c83a776..ca33799 100644 --- a/code/lab6/kern/schedule/sched.h +++ b/code/lab6/kern/schedule/sched.h @@ -5,17 +5,20 @@ #include #include +#define MAX_TIME_SLICE 20 + struct proc_struct; typedef struct { - unsigned int expires; - struct proc_struct *proc; - list_entry_t timer_link; + unsigned int expires; //the expire time + struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled + list_entry_t timer_link; //the timer list } timer_t; #define le2timer(le, member) \ to_struct((le), timer_t, member) +// init a timer static inline timer_t * timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer->expires = expires; @@ -62,9 +65,9 @@ struct run_queue { void sched_init(void); void wakeup_proc(struct proc_struct *proc); void schedule(void); -void add_timer(timer_t *timer); -void del_timer(timer_t *timer); -void run_timer_list(void); +void add_timer(timer_t *timer); // add timer to timer_list +void del_timer(timer_t *timer); // del timer from timer_list +void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc #endif /* !__KERN_SCHEDULE_SCHED_H__ */ diff --git a/code/lab6/kern/syscall/syscall.c b/code/lab6/kern/syscall/syscall.c index 3d6d3ca..4c09c15 100644 --- a/code/lab6/kern/syscall/syscall.c +++ b/code/lab6/kern/syscall/syscall.c @@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) { return 0; } -static uint32_t +static int sys_gettime(uint32_t arg[]) { return (int)ticks; } -static uint32_t +static int sys_lab6_set_priority(uint32_t arg[]) { uint32_t priority = (uint32_t)arg[0]; diff --git a/code/lab6/kern/trap/trap.c b/code/lab6/kern/trap/trap.c index e8eb143..80f7ecb 100644 --- a/code/lab6/kern/trap/trap.c +++ b/code/lab6/kern/trap/trap.c @@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) { break; case IRQ_OFFSET + IRQ_TIMER: #if 0 - LAB3 : If some page replacement algorithm need tick to change the priority of pages, + LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages, then you can add code here. #endif /* LAB1 YOUR CODE : STEP 3 */ @@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) { /* you should upate you lab1 code (just add ONE or TWO lines of code): * Every TICK_NUM cycle, you should set current process's current->need_resched = 1 */ - + /* LAB6 YOUR CODE */ + /* IMPORTANT FUNCTIONS: + * run_timer_list + *---------------------- + * you should update your lab5 code (just add ONE or TWO lines of code): + * Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler. + * You can use one funcitons to finish all these things. + */ break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); diff --git a/code/lab6/user/libs/syscall.c b/code/lab6/user/libs/syscall.c index 1571cc7..3de34f2 100644 --- a/code/lab6/user/libs/syscall.c +++ b/code/lab6/user/libs/syscall.c @@ -70,7 +70,7 @@ sys_pgdir(void) { return syscall(SYS_pgdir); } -size_t +int sys_gettime(void) { return syscall(SYS_gettime); } diff --git a/code/lab6/user/libs/syscall.h b/code/lab6/user/libs/syscall.h index d167dfe..6a20bf8 100644 --- a/code/lab6/user/libs/syscall.h +++ b/code/lab6/user/libs/syscall.h @@ -9,6 +9,7 @@ int sys_kill(int pid); int sys_getpid(void); int sys_putc(int c); int sys_pgdir(void); +int sys_gettime(void); /* FOR LAB6 ONLY */ void sys_lab6_set_priority(uint32_t priority); diff --git a/code/lab7/kern/debug/kdebug.c b/code/lab7/kern/debug/kdebug.c index fedbf5b..aaa1ef5 100644 --- a/code/lab7/kern/debug/kdebug.c +++ b/code/lab7/kern/debug/kdebug.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab7/kern/debug/kmonitor.c b/code/lab7/kern/debug/kmonitor.c new file mode 100644 index 0000000..af7c401 --- /dev/null +++ b/code/lab7/kern/debug/kmonitor.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include + +/* * + * Simple command-line kernel monitor useful for controlling the + * kernel and exploring the system interactively. + * */ + +struct command { + const char *name; + const char *desc; + // return -1 to force monitor to exit + int(*func)(int argc, char **argv, struct trapframe *tf); +}; + +static struct command commands[] = { + {"help", "Display this list of commands.", mon_help}, + {"kerninfo", "Display information about the kernel.", mon_kerninfo}, + {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, +}; + +/* return if kernel is panic, in kern/debug/panic.c */ +bool is_kernel_panic(void); + +#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) + +/***** Kernel monitor command interpreter *****/ + +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { + int argc = 0; + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + *buf ++ = '\0'; + } + if (*buf == '\0') { + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { + cprintf("Too many arguments (max %d).\n", MAXARGS); + } + argv[argc ++] = buf; + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + buf ++; + } + } + return argc; +} + +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { + char *argv[MAXARGS]; + int argc = parse(buf, argv); + if (argc == 0) { + return 0; + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { + if (strcmp(commands[i].name, argv[0]) == 0) { + return commands[i].func(argc - 1, argv + 1, tf); + } + } + cprintf("Unknown command '%s'\n", argv[0]); + return 0; +} + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { + cprintf("Welcome to the kernel debug monitor!!\n"); + cprintf("Type 'help' for a list of commands.\n"); + + if (tf != NULL) { + print_trapframe(tf); + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { + if (runcmd(buf, tf) < 0) { + break; + } + } + } +} + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { + int i; + for (i = 0; i < NCOMMANDS; i ++) { + cprintf("%s - %s\n", commands[i].name, commands[i].desc); + } + return 0; +} + +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { + print_kerninfo(); + return 0; +} + +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { + print_stackframe(); + return 0; +} + diff --git a/code/lab7/kern/debug/kmonitor.h b/code/lab7/kern/debug/kmonitor.h new file mode 100644 index 0000000..67dfe64 --- /dev/null +++ b/code/lab7/kern/debug/kmonitor.h @@ -0,0 +1,19 @@ +#ifndef __KERN_DEBUG_MONITOR_H__ +#define __KERN_DEBUG_MONITOR_H__ + +#include + +void kmonitor(struct trapframe *tf); + +int mon_help(int argc, char **argv, struct trapframe *tf); +int mon_kerninfo(int argc, char **argv, struct trapframe *tf); +int mon_backtrace(int argc, char **argv, struct trapframe *tf); +int mon_continue(int argc, char **argv, struct trapframe *tf); +int mon_step(int argc, char **argv, struct trapframe *tf); +int mon_breakpoint(int argc, char **argv, struct trapframe *tf); +int mon_watchpoint(int argc, char **argv, struct trapframe *tf); +int mon_delete_dr(int argc, char **argv, struct trapframe *tf); +int mon_list_dr(int argc, char **argv, struct trapframe *tf); + +#endif /* !__KERN_DEBUG_MONITOR_H__ */ + diff --git a/code/lab7/kern/debug/monitor.c b/code/lab7/kern/debug/monitor.c deleted file mode 100644 index 85ac06c..0000000 --- a/code/lab7/kern/debug/monitor.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* * - * Simple command-line kernel monitor useful for controlling the - * kernel and exploring the system interactively. - * */ - -struct command { - const char *name; - const char *desc; - // return -1 to force monitor to exit - int(*func)(int argc, char **argv, struct trapframe *tf); -}; - -static struct command commands[] = { - {"help", "Display this list of commands.", mon_help}, - {"kerninfo", "Display information about the kernel.", mon_kerninfo}, - {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, -}; - -/* return if kernel is panic, in kern/debug/panic.c */ -bool is_kernel_panic(void); - -#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) - -/***** Kernel monitor command interpreter *****/ - -#define MAXARGS 16 -#define WHITESPACE " \t\n\r" - -/* parse - parse the command buffer into whitespace-separated arguments */ -static int -parse(char *buf, char **argv) { - int argc = 0; - while (1) { - // find global whitespace - while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { - *buf ++ = '\0'; - } - if (*buf == '\0') { - break; - } - - // save and scan past next arg - if (argc == MAXARGS - 1) { - cprintf("Too many arguments (max %d).\n", MAXARGS); - } - argv[argc ++] = buf; - while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { - buf ++; - } - } - return argc; -} - -/* * - * runcmd - parse the input string, split it into separated arguments - * and then lookup and invoke some related commands/ - * */ -static int -runcmd(char *buf, struct trapframe *tf) { - char *argv[MAXARGS]; - int argc = parse(buf, argv); - if (argc == 0) { - return 0; - } - int i; - for (i = 0; i < NCOMMANDS; i ++) { - if (strcmp(commands[i].name, argv[0]) == 0) { - return commands[i].func(argc - 1, argv + 1, tf); - } - } - cprintf("Unknown command '%s'\n", argv[0]); - return 0; -} - -/***** Implementations of basic kernel monitor commands *****/ - -void -monitor(struct trapframe *tf) { - cprintf("Welcome to the kernel debug monitor!!\n"); - cprintf("Type 'help' for a list of commands.\n"); - - if (tf != NULL) { - print_trapframe(tf); - } - - char *buf; - while (1) { - if ((buf = readline("K> ")) != NULL) { - if (runcmd(buf, tf) < 0) { - break; - } - } - } -} - -/* mon_help - print the information about mon_* functions */ -int -mon_help(int argc, char **argv, struct trapframe *tf) { - int i; - for (i = 0; i < NCOMMANDS; i ++) { - cprintf("%s - %s\n", commands[i].name, commands[i].desc); - } - return 0; -} - -/* * - * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to - * print the memory occupancy in kernel. - * */ -int -mon_kerninfo(int argc, char **argv, struct trapframe *tf) { - print_kerninfo(); - return 0; -} - -/* * - * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to - * print a backtrace of the stack. - * */ -int -mon_backtrace(int argc, char **argv, struct trapframe *tf) { - print_stackframe(); - return 0; -} - diff --git a/code/lab7/kern/debug/monitor.h b/code/lab7/kern/debug/monitor.h deleted file mode 100644 index 2bc0854..0000000 --- a/code/lab7/kern/debug/monitor.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __KERN_DEBUG_MONITOR_H__ -#define __KERN_DEBUG_MONITOR_H__ - -#include - -void monitor(struct trapframe *tf); - -int mon_help(int argc, char **argv, struct trapframe *tf); -int mon_kerninfo(int argc, char **argv, struct trapframe *tf); -int mon_backtrace(int argc, char **argv, struct trapframe *tf); -int mon_continue(int argc, char **argv, struct trapframe *tf); -int mon_step(int argc, char **argv, struct trapframe *tf); -int mon_breakpoint(int argc, char **argv, struct trapframe *tf); -int mon_watchpoint(int argc, char **argv, struct trapframe *tf); -int mon_delete_dr(int argc, char **argv, struct trapframe *tf); -int mon_list_dr(int argc, char **argv, struct trapframe *tf); - -#endif /* !__KERN_DEBUG_MONITOR_H__ */ - diff --git a/code/lab7/kern/debug/panic.c b/code/lab7/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab7/kern/debug/panic.c +++ b/code/lab7/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab7/kern/init/init.c b/code/lab7/kern/init/init.c index 3341078..0e72880 100644 --- a/code/lab7/kern/init/init.c +++ b/code/lab7/kern/init/init.c @@ -12,9 +12,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab7/kern/mm/kmalloc.c b/code/lab7/kern/mm/kmalloc.c index aa5bb90..7ba7ed0 100644 --- a/code/lab7/kern/mm/kmalloc.c +++ b/code/lab7/kern/mm/kmalloc.c @@ -487,7 +487,7 @@ check_slab(void) { void *v0, *v1; size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = slab_allocated(); + size_t kernel_allocated_store = slab_allocated(); /* slab must be empty now */ check_slab_empty(); @@ -633,7 +633,7 @@ check_pass: check_slab_empty(); assert(slab_allocated() == 0); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == slab_allocated()); + assert(kernel_allocated_store == slab_allocated()); cprintf("check_slab() succeeded!\n"); } diff --git a/code/lab7/kern/mm/swap.c b/code/lab7/kern/mm/swap.c index 281889d..d2b5952 100644 --- a/code/lab7/kern/mm/swap.c +++ b/code/lab7/kern/mm/swap.c @@ -184,7 +184,7 @@ check_swap(void) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - //assert(PageProperty(p)); + assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); @@ -277,7 +277,7 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - cprintf("count is %d, total is %d\n",count,total); + cprintf("count is %d, total is %d\n",count,total); //assert(count == 0); cprintf("check_swap() succeeded!\n"); diff --git a/code/lab7/kern/mm/vmm.c b/code/lab7/kern/mm/vmm.c index 8ec698d..6e6325f 100644 --- a/code/lab7/kern/mm/vmm.c +++ b/code/lab7/kern/mm/vmm.c @@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable */ + /* + * LAB5 CHALLENGE ( the implmentation Copy on Write) + There are 2 situlations when code comes here. + 1) *ptep & PTE_P == 1, it means one process try to write a readonly page. + If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep. + This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method). + 2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry. + We should add the LAB3's results here. + */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page diff --git a/code/lab7/kern/process/proc.c b/code/lab7/kern/process/proc.c index 5ca778f..bd383bd 100644 --- a/code/lab7/kern/process/proc.c +++ b/code/lab7/kern/process/proc.c @@ -103,6 +103,22 @@ alloc_proc(void) { * uint32_t flags; // Process flag * char name[PROC_NAME_LEN + 1]; // Process name */ + //LAB5 YOUR CODE : (update LAB4 steps) + /* + * below fields(add in LAB5) in proc_struct need to be initialized + * uint32_t wait_state; // waiting state + * struct proc_struct *cptr, *yptr, *optr; // relations between processes + */ + //LAB6 YOUR CODE : (update LAB5 steps) + /* + * below fields(add in LAB6) in proc_struct need to be initialized + * struct run_queue *rq; // running queue contains Process + * list_entry_t run_link; // the entry linked in run queue + * int time_slice; // time slice for occupying the CPU + * skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool + * uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process + * uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t) + */ } return proc; } @@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { // 5. insert proc_struct into hash_list && proc_list // 6. call wakup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pid + + //LAB5 YOUR CODE : (update LAB4 steps) + /* Some Functions + * set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process + * ------------------- + * update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 + * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process + */ + fork_out: return ret; @@ -771,7 +796,7 @@ user_main(void *arg) { static int init_main(void *arg) { size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = kallocated(); + size_t kernel_allocated_store = kallocated(); int pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { @@ -790,7 +815,7 @@ init_main(void *arg) { assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link)); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == kallocated()); + assert(kernel_allocated_store == kallocated()); cprintf("init check memory pass.\n"); return 0; } diff --git a/code/lab7/kern/schedule/sched.c b/code/lab7/kern/schedule/sched.c index e272635..8c3ff99 100644 --- a/code/lab7/kern/schedule/sched.c +++ b/code/lab7/kern/schedule/sched.c @@ -6,6 +6,7 @@ #include #include +// the list of timer static list_entry_t timer_list; static struct sched_class *sched_class; @@ -98,6 +99,7 @@ schedule(void) { local_intr_restore(intr_flag); } +// add timer to timer_list void add_timer(timer_t *timer) { bool intr_flag; @@ -120,6 +122,7 @@ add_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// del timer from timer_list void del_timer(timer_t *timer) { bool intr_flag; @@ -139,6 +142,7 @@ del_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc void run_timer_list(void) { bool intr_flag; diff --git a/code/lab7/kern/schedule/sched.h b/code/lab7/kern/schedule/sched.h index c83a776..ca33799 100644 --- a/code/lab7/kern/schedule/sched.h +++ b/code/lab7/kern/schedule/sched.h @@ -5,17 +5,20 @@ #include #include +#define MAX_TIME_SLICE 20 + struct proc_struct; typedef struct { - unsigned int expires; - struct proc_struct *proc; - list_entry_t timer_link; + unsigned int expires; //the expire time + struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled + list_entry_t timer_link; //the timer list } timer_t; #define le2timer(le, member) \ to_struct((le), timer_t, member) +// init a timer static inline timer_t * timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer->expires = expires; @@ -62,9 +65,9 @@ struct run_queue { void sched_init(void); void wakeup_proc(struct proc_struct *proc); void schedule(void); -void add_timer(timer_t *timer); -void del_timer(timer_t *timer); -void run_timer_list(void); +void add_timer(timer_t *timer); // add timer to timer_list +void del_timer(timer_t *timer); // del timer from timer_list +void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc #endif /* !__KERN_SCHEDULE_SCHED_H__ */ diff --git a/code/lab7/kern/syscall/syscall.c b/code/lab7/kern/syscall/syscall.c index 6902e04..09f6d9f 100644 --- a/code/lab7/kern/syscall/syscall.c +++ b/code/lab7/kern/syscall/syscall.c @@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) { return 0; } -static uint32_t +static int sys_gettime(uint32_t arg[]) { return (int)ticks; } -static uint32_t +static int sys_lab6_set_priority(uint32_t arg[]) { uint32_t priority = (uint32_t)arg[0]; diff --git a/code/lab7/kern/trap/trap.c b/code/lab7/kern/trap/trap.c index e8eb143..80f7ecb 100644 --- a/code/lab7/kern/trap/trap.c +++ b/code/lab7/kern/trap/trap.c @@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) { break; case IRQ_OFFSET + IRQ_TIMER: #if 0 - LAB3 : If some page replacement algorithm need tick to change the priority of pages, + LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages, then you can add code here. #endif /* LAB1 YOUR CODE : STEP 3 */ @@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) { /* you should upate you lab1 code (just add ONE or TWO lines of code): * Every TICK_NUM cycle, you should set current process's current->need_resched = 1 */ - + /* LAB6 YOUR CODE */ + /* IMPORTANT FUNCTIONS: + * run_timer_list + *---------------------- + * you should update your lab5 code (just add ONE or TWO lines of code): + * Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler. + * You can use one funcitons to finish all these things. + */ break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); diff --git a/code/lab7/user/forktree.c b/code/lab7/user/forktree.c index c7df9ea..93f28bb 100644 --- a/code/lab7/user/forktree.c +++ b/code/lab7/user/forktree.c @@ -3,7 +3,7 @@ #include #define DEPTH 4 -#define SLEEP_TIME 400 + void forktree(const char *cur); void @@ -31,8 +31,6 @@ forktree(const char *cur) { int main(void) { - cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME); - sleep(SLEEP_TIME); forktree(""); return 0; } diff --git a/code/lab7/user/libs/syscall.c b/code/lab7/user/libs/syscall.c index 08517f2..9cb6f82 100644 --- a/code/lab7/user/libs/syscall.c +++ b/code/lab7/user/libs/syscall.c @@ -70,7 +70,7 @@ sys_pgdir(void) { return syscall(SYS_pgdir); } -size_t +int sys_gettime(void) { return syscall(SYS_gettime); } diff --git a/code/lab7/user/libs/syscall.h b/code/lab7/user/libs/syscall.h index c97d3d4..c0637ed 100644 --- a/code/lab7/user/libs/syscall.h +++ b/code/lab7/user/libs/syscall.h @@ -9,6 +9,7 @@ int sys_kill(int pid); int sys_getpid(void); int sys_putc(int c); int sys_pgdir(void); +int sys_gettime(void); /* FOR LAB6 ONLY */ void sys_lab6_set_priority(uint32_t priority); diff --git a/code/lab7/user/spin.c b/code/lab7/user/spin.c index d41b919..463f4b6 100644 --- a/code/lab7/user/spin.c +++ b/code/lab7/user/spin.c @@ -3,7 +3,7 @@ int main(void) { - int pid, ret, i ,j; + int pid, ret; cprintf("I am the parent. Forking the child...\n"); pid = fork(); if (pid== 0) { diff --git a/code/lab8/kern/debug/kdebug.c b/code/lab8/kern/debug/kdebug.c index fedbf5b..aaa1ef5 100644 --- a/code/lab8/kern/debug/kdebug.c +++ b/code/lab8/kern/debug/kdebug.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #define STACKFRAME_DEPTH 20 diff --git a/code/lab8/kern/debug/kmonitor.c b/code/lab8/kern/debug/kmonitor.c new file mode 100644 index 0000000..af7c401 --- /dev/null +++ b/code/lab8/kern/debug/kmonitor.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include + +/* * + * Simple command-line kernel monitor useful for controlling the + * kernel and exploring the system interactively. + * */ + +struct command { + const char *name; + const char *desc; + // return -1 to force monitor to exit + int(*func)(int argc, char **argv, struct trapframe *tf); +}; + +static struct command commands[] = { + {"help", "Display this list of commands.", mon_help}, + {"kerninfo", "Display information about the kernel.", mon_kerninfo}, + {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, +}; + +/* return if kernel is panic, in kern/debug/panic.c */ +bool is_kernel_panic(void); + +#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) + +/***** Kernel monitor command interpreter *****/ + +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { + int argc = 0; + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + *buf ++ = '\0'; + } + if (*buf == '\0') { + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { + cprintf("Too many arguments (max %d).\n", MAXARGS); + } + argv[argc ++] = buf; + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + buf ++; + } + } + return argc; +} + +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { + char *argv[MAXARGS]; + int argc = parse(buf, argv); + if (argc == 0) { + return 0; + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { + if (strcmp(commands[i].name, argv[0]) == 0) { + return commands[i].func(argc - 1, argv + 1, tf); + } + } + cprintf("Unknown command '%s'\n", argv[0]); + return 0; +} + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { + cprintf("Welcome to the kernel debug monitor!!\n"); + cprintf("Type 'help' for a list of commands.\n"); + + if (tf != NULL) { + print_trapframe(tf); + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { + if (runcmd(buf, tf) < 0) { + break; + } + } + } +} + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { + int i; + for (i = 0; i < NCOMMANDS; i ++) { + cprintf("%s - %s\n", commands[i].name, commands[i].desc); + } + return 0; +} + +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { + print_kerninfo(); + return 0; +} + +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { + print_stackframe(); + return 0; +} + diff --git a/code/lab8/kern/debug/kmonitor.h b/code/lab8/kern/debug/kmonitor.h new file mode 100644 index 0000000..67dfe64 --- /dev/null +++ b/code/lab8/kern/debug/kmonitor.h @@ -0,0 +1,19 @@ +#ifndef __KERN_DEBUG_MONITOR_H__ +#define __KERN_DEBUG_MONITOR_H__ + +#include + +void kmonitor(struct trapframe *tf); + +int mon_help(int argc, char **argv, struct trapframe *tf); +int mon_kerninfo(int argc, char **argv, struct trapframe *tf); +int mon_backtrace(int argc, char **argv, struct trapframe *tf); +int mon_continue(int argc, char **argv, struct trapframe *tf); +int mon_step(int argc, char **argv, struct trapframe *tf); +int mon_breakpoint(int argc, char **argv, struct trapframe *tf); +int mon_watchpoint(int argc, char **argv, struct trapframe *tf); +int mon_delete_dr(int argc, char **argv, struct trapframe *tf); +int mon_list_dr(int argc, char **argv, struct trapframe *tf); + +#endif /* !__KERN_DEBUG_MONITOR_H__ */ + diff --git a/code/lab8/kern/debug/monitor.c b/code/lab8/kern/debug/monitor.c deleted file mode 100644 index 85ac06c..0000000 --- a/code/lab8/kern/debug/monitor.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* * - * Simple command-line kernel monitor useful for controlling the - * kernel and exploring the system interactively. - * */ - -struct command { - const char *name; - const char *desc; - // return -1 to force monitor to exit - int(*func)(int argc, char **argv, struct trapframe *tf); -}; - -static struct command commands[] = { - {"help", "Display this list of commands.", mon_help}, - {"kerninfo", "Display information about the kernel.", mon_kerninfo}, - {"backtrace", "Print backtrace of stack frame.", mon_backtrace}, -}; - -/* return if kernel is panic, in kern/debug/panic.c */ -bool is_kernel_panic(void); - -#define NCOMMANDS (sizeof(commands)/sizeof(struct command)) - -/***** Kernel monitor command interpreter *****/ - -#define MAXARGS 16 -#define WHITESPACE " \t\n\r" - -/* parse - parse the command buffer into whitespace-separated arguments */ -static int -parse(char *buf, char **argv) { - int argc = 0; - while (1) { - // find global whitespace - while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { - *buf ++ = '\0'; - } - if (*buf == '\0') { - break; - } - - // save and scan past next arg - if (argc == MAXARGS - 1) { - cprintf("Too many arguments (max %d).\n", MAXARGS); - } - argv[argc ++] = buf; - while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { - buf ++; - } - } - return argc; -} - -/* * - * runcmd - parse the input string, split it into separated arguments - * and then lookup and invoke some related commands/ - * */ -static int -runcmd(char *buf, struct trapframe *tf) { - char *argv[MAXARGS]; - int argc = parse(buf, argv); - if (argc == 0) { - return 0; - } - int i; - for (i = 0; i < NCOMMANDS; i ++) { - if (strcmp(commands[i].name, argv[0]) == 0) { - return commands[i].func(argc - 1, argv + 1, tf); - } - } - cprintf("Unknown command '%s'\n", argv[0]); - return 0; -} - -/***** Implementations of basic kernel monitor commands *****/ - -void -monitor(struct trapframe *tf) { - cprintf("Welcome to the kernel debug monitor!!\n"); - cprintf("Type 'help' for a list of commands.\n"); - - if (tf != NULL) { - print_trapframe(tf); - } - - char *buf; - while (1) { - if ((buf = readline("K> ")) != NULL) { - if (runcmd(buf, tf) < 0) { - break; - } - } - } -} - -/* mon_help - print the information about mon_* functions */ -int -mon_help(int argc, char **argv, struct trapframe *tf) { - int i; - for (i = 0; i < NCOMMANDS; i ++) { - cprintf("%s - %s\n", commands[i].name, commands[i].desc); - } - return 0; -} - -/* * - * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to - * print the memory occupancy in kernel. - * */ -int -mon_kerninfo(int argc, char **argv, struct trapframe *tf) { - print_kerninfo(); - return 0; -} - -/* * - * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to - * print a backtrace of the stack. - * */ -int -mon_backtrace(int argc, char **argv, struct trapframe *tf) { - print_stackframe(); - return 0; -} - diff --git a/code/lab8/kern/debug/monitor.h b/code/lab8/kern/debug/monitor.h deleted file mode 100644 index 2bc0854..0000000 --- a/code/lab8/kern/debug/monitor.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __KERN_DEBUG_MONITOR_H__ -#define __KERN_DEBUG_MONITOR_H__ - -#include - -void monitor(struct trapframe *tf); - -int mon_help(int argc, char **argv, struct trapframe *tf); -int mon_kerninfo(int argc, char **argv, struct trapframe *tf); -int mon_backtrace(int argc, char **argv, struct trapframe *tf); -int mon_continue(int argc, char **argv, struct trapframe *tf); -int mon_step(int argc, char **argv, struct trapframe *tf); -int mon_breakpoint(int argc, char **argv, struct trapframe *tf); -int mon_watchpoint(int argc, char **argv, struct trapframe *tf); -int mon_delete_dr(int argc, char **argv, struct trapframe *tf); -int mon_list_dr(int argc, char **argv, struct trapframe *tf); - -#endif /* !__KERN_DEBUG_MONITOR_H__ */ - diff --git a/code/lab8/kern/debug/panic.c b/code/lab8/kern/debug/panic.c index 9be6c0b..62d6189 100644 --- a/code/lab8/kern/debug/panic.c +++ b/code/lab8/kern/debug/panic.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include static bool is_panic = 0; @@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) { panic_dead: intr_disable(); while (1) { - monitor(NULL); + kmonitor(NULL); } } diff --git a/code/lab8/kern/fs/devs/dev.c b/code/lab8/kern/fs/devs/dev.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/devs/dev.h b/code/lab8/kern/fs/devs/dev.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/devs/dev_disk0.c b/code/lab8/kern/fs/devs/dev_disk0.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/devs/dev_stdin.c b/code/lab8/kern/fs/devs/dev_stdin.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/devs/dev_stdout.c b/code/lab8/kern/fs/devs/dev_stdout.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/file.c b/code/lab8/kern/fs/file.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/file.h b/code/lab8/kern/fs/file.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/fs.c b/code/lab8/kern/fs/fs.c old mode 100644 new mode 100755 index 41f157c..741b889 --- a/code/lab8/kern/fs/fs.c +++ b/code/lab8/kern/fs/fs.c @@ -78,7 +78,7 @@ files_closeall(struct files_struct *filesp) { } int -dup_fs(struct files_struct *to, struct files_struct *from) { +dup_files(struct files_struct *to, struct files_struct *from) { // cprintf("[dup_fs]\n"); assert(to != NULL && from != NULL); assert(files_count(to) == 0 && files_count(from) > 0); diff --git a/code/lab8/kern/fs/fs.h b/code/lab8/kern/fs/fs.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/iobuf.c b/code/lab8/kern/fs/iobuf.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/iobuf.h b/code/lab8/kern/fs/iobuf.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/bitmap.c b/code/lab8/kern/fs/sfs/bitmap.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/bitmap.h b/code/lab8/kern/fs/sfs/bitmap.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs.c b/code/lab8/kern/fs/sfs/sfs.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs.h b/code/lab8/kern/fs/sfs/sfs.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs_fs.c b/code/lab8/kern/fs/sfs/sfs_fs.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs_inode.c b/code/lab8/kern/fs/sfs/sfs_inode.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs_io.c b/code/lab8/kern/fs/sfs/sfs_io.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sfs/sfs_lock.c b/code/lab8/kern/fs/sfs/sfs_lock.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/swap/swapfs.c b/code/lab8/kern/fs/swap/swapfs.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/swap/swapfs.h b/code/lab8/kern/fs/swap/swapfs.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sysfile.c b/code/lab8/kern/fs/sysfile.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/sysfile.h b/code/lab8/kern/fs/sysfile.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/inode.c b/code/lab8/kern/fs/vfs/inode.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/inode.h b/code/lab8/kern/fs/vfs/inode.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfs.c b/code/lab8/kern/fs/vfs/vfs.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfs.h b/code/lab8/kern/fs/vfs/vfs.h old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfsdev.c b/code/lab8/kern/fs/vfs/vfsdev.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfsfile.c b/code/lab8/kern/fs/vfs/vfsfile.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfslookup.c b/code/lab8/kern/fs/vfs/vfslookup.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/fs/vfs/vfspath.c b/code/lab8/kern/fs/vfs/vfspath.c old mode 100644 new mode 100755 diff --git a/code/lab8/kern/init/init.c b/code/lab8/kern/init/init.c index 0a95d8b..0c06aaf 100644 --- a/code/lab8/kern/init/init.c +++ b/code/lab8/kern/init/init.c @@ -13,9 +13,10 @@ #include #include #include +#include int kern_init(void) __attribute__((noreturn)); - +void grade_backtrace(void); static void lab1_switch_test(void); int diff --git a/code/lab8/kern/mm/kmalloc.c b/code/lab8/kern/mm/kmalloc.c index aa5bb90..7ba7ed0 100644 --- a/code/lab8/kern/mm/kmalloc.c +++ b/code/lab8/kern/mm/kmalloc.c @@ -487,7 +487,7 @@ check_slab(void) { void *v0, *v1; size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = slab_allocated(); + size_t kernel_allocated_store = slab_allocated(); /* slab must be empty now */ check_slab_empty(); @@ -633,7 +633,7 @@ check_pass: check_slab_empty(); assert(slab_allocated() == 0); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == slab_allocated()); + assert(kernel_allocated_store == slab_allocated()); cprintf("check_slab() succeeded!\n"); } diff --git a/code/lab8/kern/mm/swap.c b/code/lab8/kern/mm/swap.c index 281889d..d2b5952 100644 --- a/code/lab8/kern/mm/swap.c +++ b/code/lab8/kern/mm/swap.c @@ -184,7 +184,7 @@ check_swap(void) list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - //assert(PageProperty(p)); + assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); @@ -277,7 +277,7 @@ check_swap(void) struct Page *p = le2page(le, page_link); count --, total -= p->property; } - cprintf("count is %d, total is %d\n",count,total); + cprintf("count is %d, total is %d\n",count,total); //assert(count == 0); cprintf("check_swap() succeeded!\n"); diff --git a/code/lab8/kern/mm/vmm.c b/code/lab8/kern/mm/vmm.c index 26a4ab0..9c5465c 100644 --- a/code/lab8/kern/mm/vmm.c +++ b/code/lab8/kern/mm/vmm.c @@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable */ + /* + * LAB5 CHALLENGE ( the implmentation Copy on Write) + There are 2 situlations when code comes here. + 1) *ptep & PTE_P == 1, it means one process try to write a readonly page. + If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep. + This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method). + 2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry. + We should add the LAB3's results here. + */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page diff --git a/code/lab8/kern/process/proc.c b/code/lab8/kern/process/proc.c index a4c095e..e32b41a 100644 --- a/code/lab8/kern/process/proc.c +++ b/code/lab8/kern/process/proc.c @@ -106,6 +106,22 @@ alloc_proc(void) { * uint32_t flags; // Process flag * char name[PROC_NAME_LEN + 1]; // Process name */ + //LAB5 YOUR CODE : (update LAB4 steps) + /* + * below fields(add in LAB5) in proc_struct need to be initialized + * uint32_t wait_state; // waiting state + * struct proc_struct *cptr, *yptr, *optr; // relations between processes + */ + //LAB6 YOUR CODE : (update LAB5 steps) + /* + * below fields(add in LAB6) in proc_struct need to be initialized + * struct run_queue *rq; // running queue contains Process + * list_entry_t run_link; // the entry linked in run queue + * int time_slice; // time slice for occupying the CPU + * skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool + * uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process + * uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t) + */ //LAB8:EXERCISE2 YOUR CODE HINT:need add some code to init fs in proc_struct, ... } return proc; @@ -355,9 +371,10 @@ copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) { proc->context.esp = (uintptr_t)(proc->tf); } -//copy_fs&put_fs function used by do_fork in LAB8 +//copy_files&put_files function used by do_fork in LAB8 +//copy the files_struct from current to proc static int -copy_fs(uint32_t clone_flags, struct proc_struct *proc) { +copy_files(uint32_t clone_flags, struct proc_struct *proc) { struct files_struct *filesp, *old_filesp = current->filesp; assert(old_filesp != NULL); @@ -371,7 +388,7 @@ copy_fs(uint32_t clone_flags, struct proc_struct *proc) { goto bad_files_struct; } - if ((ret = dup_fs(filesp, old_filesp)) != 0) { + if ((ret = dup_files(filesp, old_filesp)) != 0) { goto bad_dup_cleanup_fs; } @@ -386,8 +403,9 @@ bad_files_struct: return ret; } +//decrease the ref_count of files, and if ref_count==0, then destroy files_struct static void -put_fs(struct proc_struct *proc) { +put_files(struct proc_struct *proc) { struct files_struct *filesp = proc->filesp; if (filesp != NULL) { if (files_count_dec(filesp) == 0) { @@ -435,6 +453,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) { // 5. insert proc_struct into hash_list && proc_list // 6. call wakup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pid + + //LAB5 YOUR CODE : (update LAB4 steps) + /* Some Functions + * set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process + * ------------------- + * update step 1: set child proc's parent to current process, make sure current process's wait_state is 0 + * update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process + */ + fork_out: return ret; @@ -470,7 +497,7 @@ do_exit(int error_code) { } current->mm = NULL; } - put_fs(current); //for LAB8 + put_files(current); //for LAB8 current->state = PROC_ZOMBIE; current->exit_code = error_code; @@ -787,7 +814,7 @@ init_main(void *arg) { } size_t nr_free_pages_store = nr_free_pages(); - size_t slab_allocated_store = kallocated(); + size_t kernel_allocated_store = kallocated(); int pid = kernel_thread(user_main, NULL, 0); if (pid <= 0) { @@ -808,7 +835,7 @@ init_main(void *arg) { assert(list_next(&proc_list) == &(initproc->list_link)); assert(list_prev(&proc_list) == &(initproc->list_link)); assert(nr_free_pages_store == nr_free_pages()); - assert(slab_allocated_store == kallocated()); + assert(kernel_allocated_store == kallocated()); cprintf("init check memory pass.\n"); return 0; } diff --git a/code/lab8/kern/schedule/sched.c b/code/lab8/kern/schedule/sched.c index e272635..e7ec74a 100644 --- a/code/lab8/kern/schedule/sched.c +++ b/code/lab8/kern/schedule/sched.c @@ -6,6 +6,7 @@ #include #include +// the list of timer static list_entry_t timer_list; static struct sched_class *sched_class; @@ -48,7 +49,7 @@ sched_init(void) { sched_class = &default_sched_class; rq = &__rq; - rq->max_time_slice = 20; + rq->max_time_slice = MAX_TIME_SLICE; sched_class->init(rq); cprintf("sched class: %s\n", sched_class->name); @@ -120,6 +121,7 @@ add_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// del timer from timer_list void del_timer(timer_t *timer) { bool intr_flag; @@ -139,6 +141,7 @@ del_timer(timer_t *timer) { local_intr_restore(intr_flag); } +// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc void run_timer_list(void) { bool intr_flag; diff --git a/code/lab8/kern/schedule/sched.h b/code/lab8/kern/schedule/sched.h index c83a776..ca33799 100644 --- a/code/lab8/kern/schedule/sched.h +++ b/code/lab8/kern/schedule/sched.h @@ -5,17 +5,20 @@ #include #include +#define MAX_TIME_SLICE 20 + struct proc_struct; typedef struct { - unsigned int expires; - struct proc_struct *proc; - list_entry_t timer_link; + unsigned int expires; //the expire time + struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled + list_entry_t timer_link; //the timer list } timer_t; #define le2timer(le, member) \ to_struct((le), timer_t, member) +// init a timer static inline timer_t * timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer->expires = expires; @@ -62,9 +65,9 @@ struct run_queue { void sched_init(void); void wakeup_proc(struct proc_struct *proc); void schedule(void); -void add_timer(timer_t *timer); -void del_timer(timer_t *timer); -void run_timer_list(void); +void add_timer(timer_t *timer); // add timer to timer_list +void del_timer(timer_t *timer); // del timer from timer_list +void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc #endif /* !__KERN_SCHEDULE_SCHED_H__ */ diff --git a/code/lab8/kern/syscall/syscall.c b/code/lab8/kern/syscall/syscall.c index 673b5eb..be23ab9 100644 --- a/code/lab8/kern/syscall/syscall.c +++ b/code/lab8/kern/syscall/syscall.c @@ -68,11 +68,11 @@ sys_pgdir(uint32_t arg[]) { return 0; } -static uint32_t +static int sys_gettime(uint32_t arg[]) { return (int)ticks; } -static uint32_t +static int sys_lab6_set_priority(uint32_t arg[]) { uint32_t priority = (uint32_t)arg[0]; diff --git a/code/lab8/kern/trap/trap.c b/code/lab8/kern/trap/trap.c index e8eb143..b063ec6 100644 --- a/code/lab8/kern/trap/trap.c +++ b/code/lab8/kern/trap/trap.c @@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) { break; case IRQ_OFFSET + IRQ_TIMER: #if 0 - LAB3 : If some page replacement algorithm need tick to change the priority of pages, + LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages, then you can add code here. #endif /* LAB1 YOUR CODE : STEP 3 */ @@ -224,15 +224,23 @@ trap_dispatch(struct trapframe *tf) { /* you should upate you lab1 code (just add ONE or TWO lines of code): * Every TICK_NUM cycle, you should set current process's current->need_resched = 1 */ - + /* LAB6 YOUR CODE */ + /* IMPORTANT FUNCTIONS: + * run_timer_list + *---------------------- + * you should update your lab5 code (just add ONE or TWO lines of code): + * Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler. + * You can use one funcitons to finish all these things. + */ break; case IRQ_OFFSET + IRQ_COM1: - c = cons_getc(); - cprintf("serial [%03d] %c\n", c, c); - break; case IRQ_OFFSET + IRQ_KBD: + // There are user level shell in LAB8, so we need change COM/KBD interrupt processing. c = cons_getc(); - cprintf("kbd [%03d] %c\n", c, c); + { + extern void dev_stdin_write(char c); + dev_stdin_write(c); + } break; //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. case T_SWITCH_TOU: diff --git a/code/lab8/libs/dirent.h b/code/lab8/libs/dirent.h old mode 100644 new mode 100755 diff --git a/code/lab8/user/forktree.c b/code/lab8/user/forktree.c index 93f28bb..c7df9ea 100644 --- a/code/lab8/user/forktree.c +++ b/code/lab8/user/forktree.c @@ -3,7 +3,7 @@ #include #define DEPTH 4 - +#define SLEEP_TIME 400 void forktree(const char *cur); void @@ -31,6 +31,8 @@ forktree(const char *cur) { int main(void) { + cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME); + sleep(SLEEP_TIME); forktree(""); return 0; } diff --git a/code/lab8/user/libs/syscall.c b/code/lab8/user/libs/syscall.c index d6ae096..5c5d978 100644 --- a/code/lab8/user/libs/syscall.c +++ b/code/lab8/user/libs/syscall.c @@ -84,7 +84,7 @@ sys_sleep(unsigned int time) { return syscall(SYS_sleep, time); } -size_t +int sys_gettime(void) { return syscall(SYS_gettime); } diff --git a/code/lab8/user/libs/syscall.h b/code/lab8/user/libs/syscall.h index 93f700a..0238fa7 100644 --- a/code/lab8/user/libs/syscall.h +++ b/code/lab8/user/libs/syscall.h @@ -11,7 +11,7 @@ int sys_getpid(void); int sys_putc(int c); int sys_pgdir(void); int sys_sleep(unsigned int time); -size_t sys_gettime(void); +int sys_gettime(void); struct stat; struct dirent; diff --git a/code/lab8/user/ls.c b/code/lab8/user/ls.c old mode 100644 new mode 100755 diff --git a/code/lab8/user/sh.c b/code/lab8/user/sh.c old mode 100644 new mode 100755 diff --git a/doc/lab0.pdf b/doc/lab0.pdf index 904a594..f7ad3c4 100644 Binary files a/doc/lab0.pdf and b/doc/lab0.pdf differ diff --git a/doc/lab1.pdf b/doc/lab1.pdf index bd2155c..2c81fdf 100644 Binary files a/doc/lab1.pdf and b/doc/lab1.pdf differ diff --git a/doc/lab2.pdf b/doc/lab2.pdf index 4ab616d..df6e7e5 100644 Binary files a/doc/lab2.pdf and b/doc/lab2.pdf differ diff --git a/doc/lab3.pdf b/doc/lab3.pdf index 98209fd..463428d 100644 Binary files a/doc/lab3.pdf and b/doc/lab3.pdf differ diff --git a/doc/lab4.pdf b/doc/lab4.pdf index 0804369..63001fa 100644 Binary files a/doc/lab4.pdf and b/doc/lab4.pdf differ diff --git a/doc/lab5.pdf b/doc/lab5.pdf index 95f3e6f..11ebecd 100644 Binary files a/doc/lab5.pdf and b/doc/lab5.pdf differ diff --git a/doc/lab6.pdf b/doc/lab6.pdf index d462fb5..899dbf0 100644 Binary files a/doc/lab6.pdf and b/doc/lab6.pdf differ diff --git a/doc/lab7.pdf b/doc/lab7.pdf index 106674a..ce8a2d6 100644 Binary files a/doc/lab7.pdf and b/doc/lab7.pdf differ diff --git a/doc/lab8.pdf b/doc/lab8.pdf index 611de79..83bb49b 100644 Binary files a/doc/lab8.pdf and b/doc/lab8.pdf differ