├── .DS_Store ├── BACKING_STORE.bin ├── InputFile.txt ├── Makefile ├── ProjectReport.txt ├── README.md ├── testinput.txt ├── vm_sim ├── vm_sim.c ├── vm_sim.o ├── vmtypes.c ├── vmtypes.h └── vmtypes.o /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedtran/VirtualMemoryManagementSim/f81c1efd1f1d447e4a1e1d285384d4cea63ee5e7/.DS_Store -------------------------------------------------------------------------------- /BACKING_STORE.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedtran/VirtualMemoryManagementSim/f81c1efd1f1d447e4a1e1d285384d4cea63ee5e7/BACKING_STORE.bin -------------------------------------------------------------------------------- /InputFile.txt: -------------------------------------------------------------------------------- 1 | 16916 2 | 62493 3 | 30198 4 | 53683 5 | 40185 6 | 28781 7 | 24462 8 | 48399 9 | 64815 10 | 18295 11 | 12218 12 | 22760 13 | 57982 14 | 27966 15 | 54894 16 | 38929 17 | 32865 18 | 64243 19 | 2315 20 | 64454 21 | 55041 22 | 18633 23 | 14557 24 | 61006 25 | 62615 26 | 7591 27 | 64747 28 | 6727 29 | 32315 30 | 60645 31 | 6308 32 | 45688 33 | 969 34 | 40891 35 | 49294 36 | 41118 37 | 21395 38 | 6091 39 | 32541 40 | 17665 41 | 3784 42 | 28718 43 | 59240 44 | 40178 45 | 60086 46 | 42252 47 | 44770 48 | 22514 49 | 3067 50 | 15757 51 | 31649 52 | 10842 53 | 43765 54 | 33405 55 | 44954 56 | 56657 57 | 5003 58 | 50227 59 | 19358 60 | 36529 61 | 10392 62 | 58882 63 | 5129 64 | 58554 65 | 58584 66 | 27444 67 | 58982 68 | 51476 69 | 6796 70 | 21311 71 | 30705 72 | 28964 73 | 41003 74 | 20259 75 | 57857 76 | 63258 77 | 36374 78 | 692 79 | 43121 80 | 48128 81 | 34561 82 | 49213 83 | 36922 84 | 59162 85 | 50552 86 | 17866 87 | 18145 88 | 3884 89 | 54388 90 | 42932 91 | 46919 92 | 58892 93 | 8620 94 | 38336 95 | 64357 96 | 23387 97 | 42632 98 | 15913 99 | 15679 100 | 22501 101 | 37540 102 | 5527 103 | 63921 104 | 62716 105 | 32874 106 | 64390 107 | 63101 108 | 61802 109 | 19648 110 | 29031 111 | 44981 112 | 28092 113 | 9448 114 | 44744 115 | 61496 116 | 31453 117 | 60746 118 | 12199 119 | 62255 120 | 21793 121 | 26544 122 | 14964 123 | 41462 124 | 56089 125 | 52038 126 | 47982 127 | 59484 128 | 50924 129 | 6942 130 | 34998 131 | 27069 132 | 51926 133 | 60645 134 | 43181 135 | 10559 136 | 4664 137 | 28578 138 | 59516 139 | 38912 140 | 63562 141 | 64846 142 | 62938 143 | 27194 144 | 28804 145 | 61703 146 | 10998 147 | 6596 148 | 37721 149 | 43430 150 | 22692 151 | 62971 152 | 47125 153 | 52521 154 | 34646 155 | 32889 156 | 13055 157 | 65416 158 | 62869 159 | 57314 160 | 12659 161 | 14052 162 | 32956 163 | 49273 164 | 50352 165 | 49737 166 | 15555 167 | 47475 168 | 15328 169 | 34621 170 | 51365 171 | 32820 172 | 48855 173 | 12224 174 | 2035 175 | 60539 176 | 14595 177 | 13853 178 | 24143 179 | 15216 180 | 8113 181 | 22640 182 | 32978 183 | 39151 184 | 19520 185 | 58141 186 | 63959 187 | 53040 188 | 55842 189 | 585 190 | 51229 191 | 64181 192 | 54879 193 | 28210 194 | 10268 195 | 15395 196 | 12884 197 | 2149 198 | 53483 199 | 59606 200 | 14981 201 | 36672 202 | 23197 203 | 36518 204 | 13361 205 | 19810 206 | 25955 207 | 62678 208 | 26021 209 | 29409 210 | 38111 211 | 58573 212 | 56840 213 | 41306 214 | 54426 215 | 3617 216 | 50652 217 | 41452 218 | 20241 219 | 31723 220 | 53747 221 | 28550 222 | 23402 223 | 21205 224 | 56181 225 | 57470 226 | 39933 227 | 34964 228 | 24781 229 | 41747 230 | 62564 231 | 58461 232 | 20858 233 | 49301 234 | 40572 235 | 23840 236 | 35278 237 | 62905 238 | 56650 239 | 11149 240 | 38920 241 | 23430 242 | 57592 243 | 3080 244 | 6677 245 | 50704 246 | 51883 247 | 62799 248 | 20188 249 | 1245 250 | 12220 251 | 17602 252 | 28609 253 | 42694 254 | 29826 255 | 13827 256 | 27336 257 | 53343 258 | 11533 259 | 41713 260 | 33890 261 | 4894 262 | 57599 263 | 3870 264 | 58622 265 | 29780 266 | 62553 267 | 2303 268 | 51915 269 | 6251 270 | 38107 271 | 59325 272 | 61295 273 | 26699 274 | 51188 275 | 59519 276 | 7345 277 | 20325 278 | 39633 279 | 1562 280 | 7580 281 | 8170 282 | 62256 283 | 35823 284 | 27790 285 | 13191 286 | 9772 287 | 7477 288 | 44455 289 | 59546 290 | 49347 291 | 36539 292 | 12453 293 | 49640 294 | 28290 295 | 44817 296 | 8565 297 | 16399 298 | 41934 299 | 45457 300 | 33856 301 | 19498 302 | 17661 303 | 63829 304 | 42034 305 | 28928 306 | 30711 307 | 8800 308 | 52335 309 | 38775 310 | 52704 311 | 24380 312 | 19602 313 | 57998 314 | 2919 315 | 8362 316 | 17884 317 | 45737 318 | 47894 319 | 59667 320 | 10385 321 | 52782 322 | 64416 323 | 40946 324 | 16778 325 | 27159 326 | 24324 327 | 32450 328 | 9108 329 | 65305 330 | 19575 331 | 11117 332 | 65170 333 | 58013 334 | 61676 335 | 63510 336 | 17458 337 | 54675 338 | 1713 339 | 55105 340 | 65321 341 | 45278 342 | 26256 343 | 64198 344 | 29441 345 | 1928 346 | 39425 347 | 32000 348 | 28549 349 | 46295 350 | 22772 351 | 58228 352 | 63525 353 | 32602 354 | 46195 355 | 55849 356 | 46454 357 | 7487 358 | 33879 359 | 42004 360 | 8599 361 | 18641 362 | 49015 363 | 26830 364 | 34754 365 | 14668 366 | 38362 367 | 38791 368 | 4171 369 | 45975 370 | 14623 371 | 62393 372 | 64658 373 | 10963 374 | 9058 375 | 51031 376 | 32425 377 | 45483 378 | 44611 379 | 63664 380 | 54920 381 | 7663 382 | 56480 383 | 1489 384 | 28438 385 | 65449 386 | 12441 387 | 58530 388 | 63570 389 | 26251 390 | 15972 391 | 35826 392 | 5491 393 | 54253 394 | 49655 395 | 5868 396 | 20163 397 | 51079 398 | 21398 399 | 32756 400 | 64196 401 | 43218 402 | 21583 403 | 25086 404 | 45515 405 | 12893 406 | 22914 407 | 58969 408 | 20094 409 | 13730 410 | 44059 411 | 28931 412 | 13533 413 | 33134 414 | 28483 415 | 1220 416 | 38174 417 | 53502 418 | 43328 419 | 4970 420 | 8090 421 | 2661 422 | 53903 423 | 11025 424 | 26627 425 | 18117 426 | 14505 427 | 61528 428 | 20423 429 | 26962 430 | 36392 431 | 11365 432 | 50882 433 | 41668 434 | 30497 435 | 36216 436 | 5619 437 | 36983 438 | 59557 439 | 36663 440 | 36436 441 | 37057 442 | 23585 443 | 58791 444 | 46666 445 | 64475 446 | 21615 447 | 41090 448 | 1771 449 | 47513 450 | 39338 451 | 1390 452 | 38772 453 | 58149 454 | 7196 455 | 9123 456 | 7491 457 | 62616 458 | 15436 459 | 17491 460 | 53656 461 | 26449 462 | 34935 463 | 19864 464 | 51388 465 | 15155 466 | 64775 467 | 47969 468 | 16315 469 | 1342 470 | 51185 471 | 6043 472 | 21398 473 | 3273 474 | 9370 475 | 35463 476 | 28205 477 | 2351 478 | 28999 479 | 47699 480 | 46870 481 | 22311 482 | 22124 483 | 22427 484 | 49344 485 | 23224 486 | 5514 487 | 20504 488 | 376 489 | 2014 490 | 38700 491 | 13098 492 | 62435 493 | 48046 494 | 63464 495 | 12798 496 | 51178 497 | 8627 498 | 27083 499 | 47198 500 | 44021 501 | 32792 502 | 43996 503 | 41126 504 | 64244 505 | 37047 506 | 60281 507 | 52904 508 | 7768 509 | 55359 510 | 3230 511 | 44813 512 | 4116 513 | 65222 514 | 28083 515 | 60660 516 | 39 517 | 328 518 | 47868 519 | 13009 520 | 22378 521 | 39304 522 | 11171 523 | 8079 524 | 52879 525 | 5123 526 | 4356 527 | 45745 528 | 32952 529 | 4657 530 | 24142 531 | 23319 532 | 13607 533 | 46304 534 | 17677 535 | 59691 536 | 50967 537 | 7817 538 | 8545 539 | 55297 540 | 52954 541 | 39720 542 | 18455 543 | 30349 544 | 63270 545 | 27156 546 | 20614 547 | 19372 548 | 48689 549 | 49386 550 | 50584 551 | 51936 552 | 34705 553 | 13653 554 | 50077 555 | 54518 556 | 41482 557 | 4169 558 | 36118 559 | 9584 560 | 18490 561 | 55420 562 | 5708 563 | 23506 564 | 15391 565 | 36368 566 | 38976 567 | 50406 568 | 49236 569 | 65035 570 | 30120 571 | 62551 572 | 46809 573 | 21687 574 | 53839 575 | 2098 576 | 12364 577 | 45366 578 | 50437 579 | 36675 580 | 55382 581 | 11846 582 | 49127 583 | 19900 584 | 20554 585 | 19219 586 | 51483 587 | 58090 588 | 39074 589 | 16060 590 | 10447 591 | 54169 592 | 20634 593 | 57555 594 | 61210 595 | 269 596 | 33154 597 | 64487 598 | 61223 599 | 47292 600 | 21852 601 | 5281 602 | 45912 603 | 32532 604 | 63067 605 | 41683 606 | 20981 607 | 33881 608 | 41785 609 | 4580 610 | 41389 611 | 28572 612 | 782 613 | 30273 614 | 62267 615 | 17922 616 | 63238 617 | 3308 618 | 26545 619 | 44395 620 | 39120 621 | 21706 622 | 7144 623 | 30244 624 | 3725 625 | 54632 626 | 30574 627 | 8473 628 | 12386 629 | 41114 630 | 57930 631 | 15341 632 | 15598 633 | 59922 634 | 18226 635 | 48162 636 | 41250 637 | 1512 638 | 2546 639 | 41682 640 | 322 641 | 880 642 | 20891 643 | 56604 644 | 40166 645 | 26791 646 | 44560 647 | 38698 648 | 64127 649 | 15028 650 | 38669 651 | 45637 652 | 43151 653 | 9465 654 | 2498 655 | 13978 656 | 16326 657 | 51442 658 | 34845 659 | 63667 660 | 39370 661 | 55671 662 | 64496 663 | 7767 664 | 6283 665 | 55884 666 | 61103 667 | 10184 668 | 39543 669 | 9555 670 | 13963 671 | 58975 672 | 19537 673 | 6101 674 | 41421 675 | 45502 676 | 29328 677 | 8149 678 | 25450 679 | 58944 680 | 50666 681 | 23084 682 | 36468 683 | 33645 684 | 25002 685 | 53715 686 | 60173 687 | 46354 688 | 4708 689 | 28208 690 | 58844 691 | 22173 692 | 8535 693 | 42261 694 | 29687 695 | 37799 696 | 22566 697 | 62520 698 | 4098 699 | 47999 700 | 49660 701 | 37063 702 | 41856 703 | 5417 704 | 48856 705 | 10682 706 | 22370 707 | 63281 708 | 62452 709 | 50532 710 | 9022 711 | 59300 712 | 58660 713 | 56401 714 | 8518 715 | 63066 716 | 63250 717 | 48592 718 | 28771 719 | 37673 720 | 60776 721 | 56438 722 | 60424 723 | 39993 724 | 56004 725 | 59002 726 | 33982 727 | 25498 728 | 57047 729 | 1401 730 | 15130 731 | 42960 732 | 61827 733 | 32442 734 | 64304 735 | 30273 736 | 38082 737 | 22404 738 | 3808 739 | 16883 740 | 23111 741 | 62417 742 | 60364 743 | 4542 744 | 14829 745 | 44964 746 | 33924 747 | 2141 748 | 19245 749 | 47168 750 | 24048 751 | 1022 752 | 23075 753 | 24888 754 | 49247 755 | 4900 756 | 22656 757 | 34117 758 | 55555 759 | 48947 760 | 59533 761 | 21312 762 | 21415 763 | 813 764 | 19419 765 | 1999 766 | 20155 767 | 21521 768 | 13670 769 | 19289 770 | 58483 771 | 41318 772 | 16151 773 | 13611 774 | 21514 775 | 13499 776 | 45583 777 | 49013 778 | 64843 779 | 63485 780 | 38697 781 | 59188 782 | 24593 783 | 57641 784 | 36524 785 | 56980 786 | 36810 787 | 6096 788 | 11070 789 | 60124 790 | 37576 791 | 15096 792 | 45247 793 | 32783 794 | 58390 795 | 60873 796 | 23719 797 | 24385 798 | 22307 799 | 17375 800 | 15990 801 | 20526 802 | 25904 803 | 42224 804 | 9311 805 | 7862 806 | 3835 807 | 30535 808 | 65179 809 | 57387 810 | 63579 811 | 4946 812 | 9037 813 | 61033 814 | 55543 815 | 50361 816 | 6480 817 | 14042 818 | 21531 819 | 39195 820 | 37511 821 | 23696 822 | 27440 823 | 28201 824 | 23072 825 | 7814 826 | 6552 827 | 43637 828 | 35113 829 | 34890 830 | 61297 831 | 45633 832 | 61431 833 | 46032 834 | 18774 835 | 62991 836 | 28059 837 | 35229 838 | 51230 839 | 14405 840 | 52242 841 | 43153 842 | 2709 843 | 47963 844 | 36943 845 | 54066 846 | 10054 847 | 43051 848 | 11525 849 | 17684 850 | 41681 851 | 27883 852 | 56909 853 | 45772 854 | 27496 855 | 46842 856 | 38734 857 | 28972 858 | 59684 859 | 11384 860 | 21018 861 | 2192 862 | 18384 863 | 13464 864 | 31018 865 | 62958 866 | 30611 867 | 1913 868 | 18904 869 | 26773 870 | 55491 871 | 21899 872 | 64413 873 | 47134 874 | 23172 875 | 7262 876 | 12705 877 | 7522 878 | 58815 879 | 34916 880 | 3802 881 | 58008 882 | 1239 883 | 63947 884 | 381 885 | 60734 886 | 48769 887 | 41938 888 | 38025 889 | 55099 890 | 56691 891 | 39530 892 | 59003 893 | 6029 894 | 20920 895 | 8077 896 | 42633 897 | 17443 898 | 53570 899 | 22833 900 | 3782 901 | 47758 902 | 22136 903 | 22427 904 | 23867 905 | 59968 906 | 62166 907 | 6972 908 | 63684 909 | 46388 910 | 41942 911 | 36524 912 | 9323 913 | 31114 914 | 22345 915 | 46463 916 | 54671 917 | 9214 918 | 7257 919 | 33150 920 | 41565 921 | 26214 922 | 3595 923 | 17932 924 | 34660 925 | 51961 926 | 58634 927 | 57990 928 | 28848 929 | 49920 930 | 18351 931 | 53669 932 | 33996 933 | 6741 934 | 64098 935 | 606 936 | 27383 937 | 63140 938 | 32228 939 | 63437 940 | 29085 941 | 65080 942 | 38753 943 | 16041 944 | 9041 945 | 42090 946 | 46388 947 | 63650 948 | 36636 949 | 21947 950 | 19833 951 | 36464 952 | 8541 953 | 12712 954 | 48955 955 | 39206 956 | 15578 957 | 49205 958 | 7731 959 | 43046 960 | 60498 961 | 9237 962 | 47706 963 | 43973 964 | 42008 965 | 27460 966 | 24999 967 | 51933 968 | 34070 969 | 65155 970 | 59955 971 | 9277 972 | 20420 973 | 44860 974 | 50992 975 | 10583 976 | 57751 977 | 23195 978 | 27227 979 | 42816 980 | 58219 981 | 37606 982 | 18426 983 | 21238 984 | 11983 985 | 48394 986 | 11036 987 | 30557 988 | 23453 989 | 49847 990 | 30032 991 | 48065 992 | 6957 993 | 2301 994 | 7736 995 | 31260 996 | 17071 997 | 8940 998 | 9929 999 | 45563 1000 | 12107 1001 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-I. 3 | DEPS = vmtypes.h 4 | 5 | %.o: %.c $(DEPS) 6 | $(CC) -c -o $@ $< $(CFLAGS) 7 | 8 | vm_sim: vmtypes.o vm_sim.o 9 | gcc -o vm_sim vm_sim.o vmtypes.o -I. 10 | -------------------------------------------------------------------------------- /ProjectReport.txt: -------------------------------------------------------------------------------- 1 | 2 | PROJECT REPORT FOR VIRTUAL MEMORY MANAGEMENT 3 | DATE: 26 APR 2018 4 | COURSE: COMP 3500 5 | AUBGID: DZT0021 6 | 7 | >> See README.md for More information and High-level Analysis << 8 | 9 | -- SOLUTION DESCRIPTION -- 10 | (1) How did you guarantee that each logical address is translated to the correct physical address? 11 | 12 | Each logical address was bit-masked to extract the rightmost 16-bits. The following function prototypes were created and implemented to extract their values (declared in vmtypes.h and implemented in vmtypes.c): 13 | 14 | // 32-Bit masking function to extract page number 15 | int getPageNumber(int mask, int value, int shift); 16 | 17 | // 32-Bit masking function to extract page offset 18 | int getOffset(int mask, int value); 19 | 20 | Once the page number and offset have been extracted from the logical address, their values are immediately stored and not manipulated. Once we find the frame number associated with the page, we then combine the frame number and offset to extract the physical address. Although the values associated with their variables change, the values are not modified more than once during each address translation. This ensures there are minimal errors and that such errors related to translation MUST be the result of some other factors (i.e. Memory leaks or otherwise). 21 | 22 | Since we do not know the physical address beforehand, we can not be entirely certain of the translation's accuracy. However, this implementation produced no obvious errors or inconsistencies after multiple executions. 23 | 24 | The physical address itself is retrieved using the left shift with the OR operator ((frame_number << SHIFT) | offset_number). This operation is used only once and for printing the results to the console. 25 | 26 | (2) How did implement the page table, physical memory, and TLB? 27 | 28 | Since the Page Table and TLB contains the same data, this implementation defined a Virtual Memory Addressing table that could be represented as either a TLB or Page Table. The type is defined as follows: 29 | 30 | typedef struct vmTable_t { 31 | int *pageNumArr; // page number array 32 | int *frameNumArr; // frame number array for this 33 | int *entryAgeArr; // Age of each index 34 | int length; 35 | int pageFaultCount; 36 | int tlbHitCount; 37 | int tlbMissCount; 38 | } vmTable_t; 39 | 40 | It can be seen that this implementation uses dynamically allocated arrays such that the program would utilize storage on the heap and scale appropriately, depending on our parameters. 41 | 42 | The physical memory itself is implemented as a 2D dynamically allocated array. These data structures are created by functions that are elaborated in file "vmtypes.c". 43 | 44 | Below are their declarations as they appear in vm_sim.c: 45 | 46 | vmTable_t* tlbTable; // The TLB Structure 47 | vmTable_t* pageTable; // The Page Table 48 | int** dram; // Physical Memory 49 | 50 | (3) Does your program realistically and accurately simulate a virtual memory system? 51 | 52 | Because this simulation uses solely software and algorithmic computations to address an abstraction for storage resources, it does not "realistically" simulate a virtual memory system. An actual MMU consists of H/W components which we simulate by creating data structures in memory. Furthermore, based on our current design specifications, it does not incorporate a replacement strategy for physical memory or the page table. Our design has enough space on the page table to accommodate the number of frames in simulated physical memory. It does, however, accurately show how resources are utilized to map memory addresses used by a program, into physical addresses in CPU memory. Also, this implementation allows main storage, as seen by a process or task, to appear as contiguous address space. 53 | 54 | 55 | (4) Did you use the Java operators for bit-masking and bit-shifting? 56 | 57 | Yes. Their implementation can be seen in the following two functions (as displayed in vmtypes.c): 58 | 59 | /* 60 | 32-Bit masking function to extract page number 61 | This function assumes a high order page number and 62 | a low order page offset 63 | @Param {mask} The int masking value we will use to perform AND operation w.r.t. value 64 | @Param {value} The int value we wish to mask 65 | @Param {shift} The relative number of bits we want to shift right after the bitwise operation 66 | @Return {int} The int representation for Page Number 67 | 68 | */ 69 | int getPageNumber(int mask, int value, int shift) { 70 | return ((value & mask)>>shift); 71 | } 72 | 73 | /* 74 | 32-Bit masking function to extract physical memory offset 75 | This function assumes a high order page number and 76 | a low order page offset 77 | @Param {mask} The int masking value we will use to perform AND operation w.r.t. value 78 | @Param {value} The int value we wish to mask 79 | @Return {int} The int representation for physical memory offset 80 | 81 | */ 82 | int getOffset(int mask, int value) { 83 | return value & mask; 84 | } 85 | 86 | (5) When a TLB miss occurs, how do you decide which entry to replace? 87 | 88 | The following function prototypes define that behavior: 89 | 90 | // Function Prototypes 91 | void translateAddress(); 92 | void readFromStore(int pageNumber); 93 | void tlbFIFOinsert(int pageNumber, int frameNumber); 94 | void tlbLRUinsert(int pageNumber, int frameNumber); 95 | int getOldestEntry(int tlbSize); 96 | 97 | The user determines which algorithm they would like to execute a TLB insert. Each function has several comments detailing each logical step. For FIFO, we insert entries into their respective fields until the TLB can no longer fit newer entries. We then overwrite the last entry in the TLB with our newest entry and then programmatically shift the fields of every value in the table such that the first entry that made its way into the buffer is no longer in the table. For LRU, we enter in each new entry and then when the table is full we increment the age counter for all entries. The oldest entry gets replaced. If there are entries which have the same age, the first one is selected. 98 | 99 | -- GENERALITY AND PERFORMANCE CRITERIA -- 100 | (1) How general is your solution? 101 | 102 | The solution is very general. All that needs to be modified are constants which define the system parameters for the virtual memory. These constants are defined as follows: 103 | 104 | #define FRAME_SIZE 256 // Size of each frame 105 | #define TOTAL_FRAME_COUNT 256 // Total number of frames in physical memory 106 | #define PAGE_MASK 0xFF00 // Masks everything but the page number 107 | #define OFFSET_MASK 0xFF // Masks everything but the offset 108 | #define SHIFT 8 // Amount to shift when bitmasking 109 | #define TLB_SIZE 16 // size of the TLB 110 | #define PAGE_TABLE_SIZE 256 // size of the page table 111 | #define MAX_ADDR_LEN 10 // The number of characters to read for each line from input file. 112 | #define PAGE_READ_SIZE 256 // Number of bytes to read 113 | 114 | There is no need to modify other values, as the program will execute on these values as long as the user is aware of its application. 115 | 116 | (2) How easy would it be to change parameters such as the size of the TLB? 117 | 118 | Very easy. See last question. 119 | 120 | (3) Does your program only load pages from the backing store when they are needed? 121 | 122 | Yes, there is absolutely NO reason to access the BACKING_STORE if a frame number is found to be in the TLB or Page Table. It would be highly inefficient to access the backing store in such a case. The function translateAddress() handles whether or not backing store access is required. Additionally, this system implements a function that calculates the average time complexity for accessing the backing store. With the current input size, it takes an average of ~5 milliseconds to read from the backing store. However, as secondary memory and virtual memory size may vary, this time could have significant non-linear growth. Regardless of the time it takes, it still incurs a time penalty that would otherwise be unnecessary if we accessed it during every address translation. 123 | 124 | (4) Does your solution allow the physical address space to be smaller than the virtual address space? 125 | 126 | This implementation does allow for the physical address space to be smaller, due to the fact we use dynamic memory allocation. As a result, we always allocate the right amount of memory to hold the working set. The same applies for the page table and TLB despite the fact they are generally fixed-size. In any event, virtual memory is typically larger than physical memory - there wouldn't be much reason for virtual memory mappings if virtual memory and physical memory were the same size [source](https://stackoverflow.com/a/14347298). Furthermore, the user will define the size of their desired physical and virtual memory, as specified by the constants. 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VirtualMemoryManagementSim 2 | A C-Program that simulates Virtual Memory Management based on a text file input of logical addresses which represents sequential instructions with address range 0 thru 216 - 1. See the [Project Report](https://github.com/zedtran/VirtualMemoryManagementSim/blob/master/ProjectReport.txt) for more details regarding usage. 3 | 4 | ## Overview 5 | This project is the design and implementation of a standalone virtual memory manager, where there is a software-managed TLB. The program is responsible to (1) load a [file](https://github.com/zedtran/VirtualMemoryManagementSim/blob/master/InputFile.txt) containing a list of logical addresses, (2) translate logical addresses into physical addresses for a virtual address space of size 216 = 65,536 bytes, and (3) output the value of the byte stored at the translated physical address. 6 | 7 | ## Information about the Simulated Virtual Memory 8 | #### 16-bit Logical Addresses 9 | The program reads a file containing a list of 32-bit integer numbers, which represent 32-bit logical addresses. It should be noted that the program only deals with 16-bit addresses. Thus, this simulation implements masking for the rightmost 16 bits of each logical address loaded from the file. 10 | 11 | 12 | | Page Number | Offset | 13 | |:---------------------------------:|:---------------------------------:| 14 | | Bits 15 - 8 | Bits 7 - 0 | 15 | 16 | 17 | ## System Parameters of the Virtual Memory 18 | The page table size is 28 bytes; the TLB contains 16 entries. The page size is 2^8^ bytes, which is the same as the frame size. There are a total of 256 frames in the physical memory, meaning that the total physical memory capability is 65,536 bytes (i.e., 256 frames * 256 bytes/frame). The system parameters of the simulated virtual memory is summarized below. 19 | 20 | * Page table size: _28_ 21 | * Number of TLB entries: _16_ 22 | * Page size: _28 bytes_ 23 | * Frame size: _28 bytes_ 24 | * Number of frames: _256_ 25 | * Physical memory size: _65,536 bytes_ 26 | 27 | ## How Page Faults are Handled 28 | This virtual memory system implements demand paging. The backing store is simulated by a file called “BACKING_STORE.bin”. BACKING_STORE is a binary file of 65,536 bytes. When a page fault occurs, the virtual memory system will perform the following four steps: 29 | 30 | * Step 1: read a 256-byte page from the file BACKING_STORE and 31 | * Step 2: store the loaded page frame in the physical memory. 32 | * Step 3: Update the page table 33 | * Step 4: Update the TLB 34 | 35 | For example, if a logical address with page number 15 triggers a page fault, your virtual memory system will read in page 15 from the file BACKING_STORE. Then, the loaded page frame is placed in the physical memory. After the page frame is fetched from the disk, the page table and the TLB will be updated accordingly. Subsequent access of page 15 will be referenced by accessing either the TLB or the page table. 36 | 37 | ## Compilation and Program Execution 38 | 39 | - [ ] Compiled and tested using clang compiler: `$ clang -o vm_sim vm_sim.c vmtypes.c` 40 | - [ ] ALSO Compiled and tested using gcc: `$ gcc -o vm_sim vm_sim.c vmtypes.c` 41 | - [ ] Created Makefile with gcc as Constant 42 | - [ ] SIMPLY download this project and execute `make` in command line 43 | - [ ] Execute program with `$ ./vm_sim InputFile.txt` or use an appropriate `[input].txt` file 44 | 45 | ## Relevant Sources Cited 46 | 47 | * [For how to create smart arrays](https://www.youtube.com/watch?v=QhwFwWpq4dQ) 48 | * [Dynamic Allocation of 2D Array in struct](https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/) 49 | * [For creating physical memory struct](https://www.cs.cmu.edu/~ab/15-123S09/lectures/Lecture%2011%20%20-%20%20Array%20of%20Linked%20Lists.pdf) 50 | * [More dynamic allocation](https://www.youtube.com/watch?v=t72BzxMAQKs) 51 | * [Double Pointer Return Type](https://stackoverflow.com/a/4339353) 52 | * [How to Perform Bit Masking](https://stackoverflow.com/a/10493604) 53 | * [Proper malloc() error output and exiting](https://stackoverflow.com/a/2574771) 54 | * [How to use fgets() function](https://stackoverflow.com/a/19609987) 55 | * [How to measure clock time](https://stackoverflow.com/a/12743207) 56 | * NOTE: Other sources were also used to gain understanding of Virtual Memory Management concepts 57 | 58 | ## Sample Input/Output 59 | 60 | #### Upon Running the Program the user will be prompted with the following 61 | 62 | ``` 63 | Welcome to Don's VM Simulator Version 1.0 64 | Number of logical pages: 256 65 | Page size: 256 bytes 66 | Page Table Size: 256 67 | TLB Size: 16 entries 68 | Number of Physical Frames: 256 69 | Physical Memory Size: 65536 bytes 70 | Display All Physical Addresses? [y/n]: n 71 | Choose TLB Replacement Strategy [1: FIFO, 2: LRU]: 1 72 | ``` 73 | #### User chooses Display Option and TLB Replacement Strategy 74 | 75 | If FIFO is selected, program displays to console: 76 | 77 | ``` 78 | Results Using FIFO Algorithm: 79 | Number of translated addresses = 1000 80 | Page Faults = 244 81 | Page Fault Rate = 24.400 % 82 | TLB Hits = 51 83 | TLB Hit Rate = 5.100 % 84 | Average time spent retrieving data from backing store: 5.537 millisec 85 | 86 | ``` 87 | If LRU is selected, program displays to console: 88 | 89 | ``` 90 | Welcome to Don's VM Simulator Version 1.0 91 | Number of logical pages: 256 92 | Page size: 256 bytes 93 | Page Table Size: 256 94 | TLB Size: 16 entries 95 | Number of Physical Frames: 256 96 | Physical Memory Size: 65536 bytes 97 | Display All Physical Addresses? [y/n]: n 98 | Choose TLB Replacement Strategy [1: FIFO, 2: LRU]: 2 99 | 100 | ----------------------------------------------------------------------------------- 101 | 102 | Results Using LRU Algorithm: 103 | Number of translated addresses = 1000 104 | Page Faults = 244 105 | Page Fault Rate = 24.400 % 106 | TLB Hits = 56 107 | TLB Hit Rate = 5.600 % 108 | Average time spent retrieving data from backing store: 4.598 millisec 109 | 110 | ----------------------------------------------------------------------------------- 111 | ``` 112 | 113 | ### Displayed Physical Addresses 114 | 115 | If user chooses to display physical addresses, a similar output will immediately precede the results: 116 | 117 | ``` 118 | ----------------------------------------------------------------------------------- 119 | Virtual address: 16916 Physical address: 20 Value: 0 120 | Virtual address: 62493 Physical address: 285 Value: 0 121 | Virtual address: 30198 Physical address: 758 Value: 29 122 | Virtual address: 53683 Physical address: 947 Value: 108 123 | Virtual address: 40185 Physical address: 1273 Value: 0 124 | Virtual address: 28781 Physical address: 1389 Value: 0 125 | Virtual address: 24462 Physical address: 1678 Value: 23 126 | Virtual address: 48399 Physical address: 1807 Value: 67 127 | Virtual address: 64815 Physical address: 2095 Value: 75 128 | Virtual address: 18295 Physical address: 2423 Value: -35 129 | Virtual address: 12218 Physical address: 2746 Value: 11 130 | Virtual address: 22760 Physical address: 3048 Value: 0 131 | Virtual address: 57982 Physical address: 3198 Value: 56 132 | Virtual address: 27966 Physical address: 3390 Value: 27 133 | ... 134 | ----------------------------------------------------------------------------------- 135 | ``` 136 | 137 | -------------------------------------------------------------------------------- /testinput.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 259 3 | 515 4 | 771 5 | 1027 6 | 1283 7 | 7 8 | 263 9 | 519 10 | 775 11 | 1031 12 | 1287 13 | -------------------------------------------------------------------------------- /vm_sim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedtran/VirtualMemoryManagementSim/f81c1efd1f1d447e4a1e1d285384d4cea63ee5e7/vm_sim -------------------------------------------------------------------------------- /vm_sim.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "vmtypes.h" 8 | 9 | 10 | /* 11 | File: vm_sim.c 12 | Name: Tran, Don 13 | Date: 20 April 2018 14 | Course: COMP3500 - See: www.eng.auburn.edu/files/acad_depts/csse/syllabi/comp3500.2016.pdf 15 | */ 16 | 17 | #define FRAME_SIZE 256 // Size of each frame 18 | #define TOTAL_FRAME_COUNT 256 // Total number of frames in physical memory 19 | #define PAGE_MASK 0xFF00 // Masks everything but the page number 20 | #define OFFSET_MASK 0xFF // Masks everything but the offset 21 | #define SHIFT 8 // Amount to shift when bitmasking 22 | #define TLB_SIZE 16 // size of the TLB 23 | #define PAGE_TABLE_SIZE 256 // size of the page table 24 | #define MAX_ADDR_LEN 10 // The number of characters to read for each line from input file. 25 | #define PAGE_READ_SIZE 256 // Number of bytes to read 26 | 27 | typedef enum { false = 0, true = !false } bool; // Simple true or false boolean -- unsure if I want to use yet 28 | 29 | /* 30 | vmTable is a generic struct defined type that is used to implement any 31 | number of caches for logical address translations. It contains the following components: 32 | (1) int *pageNumArr; // page number array 33 | (2) int *frameNumArr; // frame number array for this 34 | (3) int *entryAgeArr; // the age of each entry 35 | (4) int length; // The table size 36 | (5) int pageFaultCount; // Represents number of page faults, if implemeneted as Page Table 37 | (6) int tlbHitCount; // Represents TLB hit count 38 | (7) int tlbMissCount; // Represents TLB misses 39 | */ 40 | 41 | vmTable_t* tlbTable; // The TLB Structure 42 | vmTable_t* pageTable; // The Page Table 43 | int** dram; // Physical Memory 44 | 45 | char algo_choice; // menu stdin 46 | char display_choice; // menu stdin 47 | 48 | 49 | int nextTLBentry = 0; // Tracks the next available index of entry into the TLB 50 | int nextPage = 0; // Tracks the next available page in the page table 51 | int nextFrame = 0; // Tracks the next available frame TLB or Page Table 52 | 53 | // input file and backing store 54 | FILE* address_file; 55 | FILE* backing_store; 56 | 57 | // how we store reads from input file 58 | char addressReadBuffer[MAX_ADDR_LEN]; 59 | int virtual_addr; 60 | int page_number; 61 | int offset_number; 62 | 63 | // Generating length of time for a function 64 | clock_t start, end; 65 | double cpu_time_used; 66 | int functionCallCount = 0; 67 | 68 | // the buffer containing reads from backing store 69 | signed char fileReadBuffer[PAGE_READ_SIZE]; 70 | 71 | // the translatedValue of the byte (signed char) in memory 72 | signed char translatedValue; 73 | 74 | // Function Prototypes 75 | void translateAddress(); 76 | void readFromStore(int pageNumber); 77 | void tlbFIFOinsert(int pageNumber, int frameNumber); 78 | void tlbLRUinsert(int pageNumber, int frameNumber); 79 | int getOldestEntry(int tlbSize); 80 | double getAvgTimeInBackingStore(); 81 | 82 | 83 | // main opens necessary files and calls on translateAddress for every entry in the addresses file 84 | int main(int argc, char *argv[]) 85 | { 86 | tlbTable = createVMtable(TLB_SIZE); // The TLB Structure 87 | pageTable = createVMtable(PAGE_TABLE_SIZE); // The Page Table 88 | dram = dramAllocate(TOTAL_FRAME_COUNT, FRAME_SIZE); // Physical Memory 89 | int translationCount = 0; 90 | char* algoName; 91 | 92 | // perform basic error checking 93 | if (argc != 2) { 94 | fprintf(stderr,"Usage: ./vm_sim [input file]\n"); 95 | return -1; 96 | } 97 | 98 | // open the file containing the backing store 99 | backing_store = fopen("BACKING_STORE.bin", "rb"); 100 | 101 | if (backing_store == NULL) { 102 | fprintf(stderr, "Error opening BACKING_STORE.bin %s\n","BACKING_STORE.bin"); 103 | return -1; 104 | } 105 | 106 | // open the file containing the logical addresses 107 | address_file = fopen(argv[1], "r"); 108 | 109 | if (address_file == NULL) { 110 | fprintf(stderr, "Error opening %s. Expecting [InputFile].txt or equivalent.\n",argv[1]); 111 | return -1; 112 | } 113 | 114 | printf("\nWelcome to Don's VM Simulator Version 1.0"); 115 | printf("\nNumber of logical pages: %d\nPage size: %d bytes\nPage Table Size: %d\nTLB Size: %d entries\nNumber of Physical Frames: %d\nPhysical Memory Size: %d bytes", PAGE_TABLE_SIZE, PAGE_READ_SIZE, PAGE_TABLE_SIZE, TLB_SIZE, FRAME_SIZE, PAGE_READ_SIZE * FRAME_SIZE); 116 | 117 | 118 | do { 119 | printf("\nDisplay All Physical Addresses? [y/n]: "); 120 | scanf("\n%c", &display_choice); 121 | } while (display_choice != 'n' && display_choice != 'y'); 122 | 123 | do { 124 | printf("Choose TLB Replacement Strategy [1: FIFO, 2: LRU]: "); 125 | scanf("\n%c", &algo_choice); 126 | } while (algo_choice != '1' && algo_choice != '2'); 127 | 128 | 129 | 130 | // Read through the input file and output each virtual address 131 | while (fgets(addressReadBuffer, MAX_ADDR_LEN, address_file) != NULL) { 132 | virtual_addr = atoi(addressReadBuffer); // converting from ascii to int 133 | 134 | // 32-bit masking function to extract page number 135 | page_number = getPageNumber(PAGE_MASK, virtual_addr, SHIFT); 136 | 137 | // 32-bit masking function to extract page offset 138 | offset_number = getOffset(OFFSET_MASK, virtual_addr); 139 | 140 | // Get the physical address and translatedValue stored at that address 141 | translateAddress(algo_choice); 142 | translationCount++; // increment the number of translated addresses 143 | } 144 | 145 | // Determining stdout algo name for Menu 146 | if (algo_choice == '1') { 147 | algoName = "FIFO"; 148 | } 149 | else { 150 | algoName = "LRU"; 151 | } 152 | 153 | printf("\n-----------------------------------------------------------------------------------\n"); 154 | // calculate and print out the stats 155 | printf("\nResults Using %s Algorithm: \n", algoName); 156 | printf("Number of translated addresses = %d\n", translationCount); 157 | double pfRate = (double)pageTable->pageFaultCount / (double)translationCount; 158 | double TLBRate = (double)tlbTable->tlbHitCount / (double)translationCount; 159 | 160 | printf("Page Faults = %d\n", pageTable->pageFaultCount); 161 | printf("Page Fault Rate = %.3f %%\n",pfRate * 100); 162 | printf("TLB Hits = %d\n", tlbTable->tlbHitCount); 163 | printf("TLB Hit Rate = %.3f %%\n", TLBRate * 100); 164 | printf("Average time spent retrieving data from backing store: %.3f millisec\n", getAvgTimeInBackingStore()); 165 | printf("\n-----------------------------------------------------------------------------------\n"); 166 | 167 | // close the input file and backing store 168 | fclose(address_file); 169 | fclose(backing_store); 170 | 171 | // NOTE: REMEMBER TO FREE DYNAMICALLY ALLOCATED MEMORY 172 | freeVMtable(&tlbTable); 173 | freeVMtable(&pageTable); 174 | freeDRAM(&dram, TOTAL_FRAME_COUNT); 175 | return 0; 176 | } 177 | 178 | 179 | /* 180 | This function takes the virtual address and translates 181 | into physical addressing, and retrieves the translatedValue stored 182 | @Param algo_type Is '1' for tlbFIFOinsert and '2' for tlbLRUinsert 183 | */ 184 | void translateAddress() 185 | { 186 | // First try to get page from TLB 187 | int frame_number = -1; // Assigning -1 to frame_number means invalid initially 188 | 189 | /* 190 | Look through the TLB to see if memory page exists. 191 | If found, extract frame number and increment hit count 192 | */ 193 | for (int i = 0; i < tlbTable->length; i++) { 194 | if (tlbTable->pageNumArr[i] == page_number) { 195 | frame_number = tlbTable->frameNumArr[i]; 196 | tlbTable->tlbHitCount++; 197 | break; 198 | } 199 | } 200 | 201 | /* 202 | We now need to see if there was a TLB miss. 203 | If so, increment the tlb miss count and go through 204 | the page table to see if the page number exists. If not on page table, 205 | read secondary storage (dram) and increment page table fault count. 206 | */ 207 | if (frame_number == -1) { 208 | tlbTable->tlbMissCount++; // Increment the miss count 209 | // walk the contents of the page table 210 | for(int i = 0; i < nextPage; i++){ 211 | if(pageTable->pageNumArr[i] == page_number){ // If the page is found in those contents 212 | frame_number = pageTable->frameNumArr[i]; // Extract the frame_number 213 | break; // Found in pageTable 214 | } 215 | } 216 | // NOTE: Page Table Fault Encountered 217 | if(frame_number == -1) { // if the page is not found in those contents 218 | pageTable->pageFaultCount++; // Increment the number of page faults 219 | // page fault, call to readFromStore to get the frame into physical memory and the page table 220 | start = clock(); 221 | readFromStore(page_number); 222 | cpu_time_used += (double)(clock() - start) / CLOCKS_PER_SEC; 223 | functionCallCount++; 224 | frame_number = nextFrame - 1; // And set the frame_number to the current nextFrame index 225 | } 226 | } 227 | 228 | if (algo_choice == '1') { 229 | // Call function to insert the page number and frame number into the TLB 230 | tlbFIFOinsert(page_number, frame_number); 231 | } 232 | else { 233 | tlbLRUinsert(page_number, frame_number); 234 | } 235 | 236 | // Frame number and offset used to get the signed translatedValue stored at that address 237 | translatedValue = dram[frame_number][offset_number]; 238 | 239 | // FOR TESTING -- printf("\nFrame Number: %d; Offset: %d; ", frame_number, offset_number); 240 | 241 | if (display_choice == 'y') { 242 | // output the virtual address, physical address and translatedValue of the signed char to the console 243 | printf("\nVirtual address: %d\t\tPhysical address: %d\t\tValue: %d", virtual_addr, (frame_number << SHIFT) | offset_number, translatedValue); 244 | } 245 | } 246 | 247 | // Function to read from the backing store and bring the frame into physical memory and the page table 248 | void readFromStore(int pageNumber) 249 | { 250 | // first seek to byte PAGE_READ_SIZE in the backing store 251 | // SEEK_SET in fseek() seeks from the beginning of the file 252 | if (fseek(backing_store, pageNumber * PAGE_READ_SIZE, SEEK_SET) != 0) { 253 | fprintf(stderr, "Error seeking in backing store\n"); 254 | } 255 | 256 | // now read PAGE_READ_SIZE bytes from the backing store to the fileReadBuffer 257 | if (fread(fileReadBuffer, sizeof(signed char), PAGE_READ_SIZE, backing_store) == 0) { 258 | fprintf(stderr, "Error reading from backing store\n"); 259 | } 260 | 261 | // Load the bits into the first available frame in the physical memory 2D array 262 | for (int i = 0; i < PAGE_READ_SIZE; i++) { 263 | dram[nextFrame][i] = fileReadBuffer[i]; 264 | } 265 | 266 | // Then we want to load the frame number into the page table in the next frame 267 | pageTable->pageNumArr[nextPage] = pageNumber; 268 | pageTable->frameNumArr[nextPage] = nextFrame; 269 | 270 | // increment the counters that track the next available frames 271 | nextFrame++; 272 | nextPage++; 273 | 274 | 275 | } 276 | 277 | 278 | // Function to insert a page number and frame number into the TLB with a FIFO replacement 279 | void tlbFIFOinsert(int pageNumber, int frameNumber) 280 | { 281 | int i; 282 | 283 | // If it's already in the TLB, break 284 | for(i = 0; i < nextTLBentry; i++){ 285 | if(tlbTable->pageNumArr[i] == pageNumber){ 286 | break; 287 | } 288 | } 289 | 290 | // if the number of entries is equal to the index 291 | if(i == nextTLBentry){ 292 | if(nextTLBentry < TLB_SIZE){ // IF TLB Buffer has open positions 293 | tlbTable->pageNumArr[nextTLBentry] = pageNumber; // insert the page and frame on the end 294 | tlbTable->frameNumArr[nextTLBentry] = frameNumber; 295 | } 296 | else{ // No room in TLB Buffer 297 | 298 | // Replace the last TLB entry with our new entry 299 | tlbTable->pageNumArr[nextTLBentry - 1] = pageNumber; 300 | tlbTable->frameNumArr[nextTLBentry - 1] = frameNumber; 301 | 302 | // Then shift up all the TLB entries by 1 so we can maintain FIFO order 303 | for(i = 0; i < TLB_SIZE - 1; i++){ 304 | tlbTable->pageNumArr[i] = tlbTable->pageNumArr[i + 1]; 305 | tlbTable->frameNumArr[i] = tlbTable->frameNumArr[i + 1]; 306 | } 307 | } 308 | } 309 | 310 | // If the index is not equal to the number of entries 311 | else{ 312 | 313 | for(i = i; i < nextTLBentry - 1; i++){ // iterate through up to one less than the number of entries 314 | // Move everything over in the arrays 315 | tlbTable->pageNumArr[i] = tlbTable->pageNumArr[i + 1]; 316 | tlbTable->frameNumArr[i] = tlbTable->frameNumArr[i + 1]; 317 | } 318 | if(nextTLBentry < TLB_SIZE){ // if there is still room in the array, put the page and frame on the end 319 | // Insert the page and frame on the end 320 | tlbTable->pageNumArr[nextTLBentry] = pageNumber; 321 | tlbTable->frameNumArr[nextTLBentry] = frameNumber; 322 | 323 | } 324 | else{ // Otherwise put the page and frame on the number of entries - 1 325 | tlbTable->pageNumArr[nextTLBentry - 1] = pageNumber; 326 | tlbTable->frameNumArr[nextTLBentry - 1] = frameNumber; 327 | } 328 | } 329 | if(nextTLBentry < TLB_SIZE) { // If there is still room in the arrays, increment the number of entries 330 | nextTLBentry++; 331 | } 332 | } 333 | 334 | 335 | // Function to insert a page number and frame number into the TLB with a LRU replacement 336 | void tlbLRUinsert(int pageNumber, int frameNumber) 337 | { 338 | 339 | bool freeSpotFound = false; 340 | bool alreadyThere = false; 341 | int replaceIndex = -1; 342 | 343 | // SEEK -- > Find the index to replace and increment age for all other entries 344 | for (int i = 0; i < TLB_SIZE; i++) { 345 | if ((tlbTable->pageNumArr[i] != pageNumber) && (tlbTable->pageNumArr[i] != 0)) { 346 | // If entry is not in TLB and not a free spot, increment its age 347 | tlbTable->entryAgeArr[i]++; 348 | } 349 | else if ((tlbTable->pageNumArr[i] != pageNumber) && (tlbTable->pageNumArr[i] == 0)) { 350 | // Available spot in TLB found 351 | if (!freeSpotFound) { 352 | replaceIndex = i; 353 | freeSpotFound = true; 354 | } 355 | } 356 | else if (tlbTable->pageNumArr[i] == pageNumber) { 357 | // Entry is already in TLB -- Reset its age 358 | if(!alreadyThere) { 359 | tlbTable->entryAgeArr[i] = 0; 360 | alreadyThere = true; 361 | } 362 | } 363 | } 364 | 365 | // REPLACE 366 | if (alreadyThere) { 367 | return; 368 | } 369 | else if (freeSpotFound) { // If we found a free spot, insert 370 | tlbTable->pageNumArr[replaceIndex] = pageNumber; // Insert into free spot 371 | tlbTable->frameNumArr[replaceIndex] = frameNumber; 372 | tlbTable->entryAgeArr[replaceIndex] = 0; 373 | } 374 | else { // No more free spots -- Need to replace the oldest entry 375 | replaceIndex = getOldestEntry(TLB_SIZE); 376 | tlbTable->pageNumArr[replaceIndex] = pageNumber; // Insert into oldest entry 377 | tlbTable->frameNumArr[replaceIndex] = frameNumber; 378 | tlbTable->entryAgeArr[replaceIndex] = 0; 379 | 380 | } 381 | } 382 | 383 | // Finds the oldest entry in TLB and returns the replacement Index 384 | int getOldestEntry(int tlbSize) { 385 | int i, max, index; 386 | 387 | max = tlbTable->entryAgeArr[0]; 388 | index = 0; 389 | 390 | for (i = 1; i < tlbSize; i++) { 391 | if (tlbTable->entryAgeArr[i] > max) { 392 | index = i; 393 | max = tlbTable->entryAgeArr[i]; 394 | } 395 | } 396 | return index; 397 | } 398 | 399 | // Just computes the average time complexity of accessing the backing store 400 | double getAvgTimeInBackingStore() { 401 | double temp = (double) cpu_time_used / (double) functionCallCount; 402 | return temp * 1000000; 403 | } 404 | -------------------------------------------------------------------------------- /vm_sim.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedtran/VirtualMemoryManagementSim/f81c1efd1f1d447e4a1e1d285384d4cea63ee5e7/vm_sim.o -------------------------------------------------------------------------------- /vmtypes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "vmtypes.h" /* Include the header (not strictly necessary here) */ 5 | 6 | /* 7 | Creates a Table that Contains array indexable values for Page 8 | Number and Frame Number for direct translation lookaside buffer (TLB) 9 | or page table entry (PTE). 10 | 11 | @Param {length} Represents the int length of the constructed internal arrays 12 | @Return {vmTable_t*} A pointer to the the created table which will represent either the TLB or Page Table 13 | */ 14 | vmTable_t* createVMtable(int length) 15 | { 16 | vmTable_t* new_table = malloc(sizeof(vmTable_t)); 17 | new_table->length = length; 18 | new_table->pageNumArr = malloc(sizeof(int) * length); 19 | new_table->frameNumArr = malloc(sizeof(int) * length); 20 | new_table->entryAgeArr = malloc(sizeof(int) * length); 21 | new_table->pageFaultCount = 0; 22 | new_table->tlbHitCount = 0; 23 | new_table->tlbMissCount = 0; 24 | 25 | for (int i = 0; i < length; i++) { 26 | new_table->pageNumArr[i] = 0; 27 | } 28 | 29 | // If there is not enough memory on the heap to make a call to malloc() // Notify and Exit 30 | if(new_table == NULL || new_table->pageNumArr == NULL || new_table->frameNumArr == NULL) { 31 | printf("Error - Could not allocate a new Virtual Memory Addressing Table!\r\n"); 32 | exit(-1); 33 | } 34 | return new_table; 35 | } 36 | /* 37 | Method to free dynamically allocated memory 38 | 39 | @Param {table} The TLB or Page Table we want to clear from memory 40 | */ 41 | void freeVMtable(vmTable_t** table) 42 | { 43 | if ((*table)->pageNumArr != NULL) { 44 | free((*table)->pageNumArr); 45 | } 46 | if ((*table)->frameNumArr != NULL) { 47 | free((*table)->frameNumArr); 48 | } 49 | if ((*table)->entryAgeArr != NULL) { 50 | free((*table)->entryAgeArr); 51 | } 52 | free(*table); 53 | } 54 | /* 55 | This function prints contents of the vmTable 56 | 57 | @Param {tableToView} The TLB or Page Table who's contents we want to view in console 58 | */ 59 | void displayTable(vmTable_t** tableToView) 60 | { 61 | printf("\n********************* SEQUENCE START ****************************\n "); 62 | for (int i = 0; i < (*tableToView)->length; i++) { 63 | printf("Index(%d) := Page Number: %d\tFrame Number: %d\n", i, (*tableToView)->pageNumArr[i], (*tableToView)->frameNumArr[i]); 64 | } 65 | printf("\n********************* SEQUENCE END ***************************\n "); 66 | } 67 | 68 | /* DECIDED NOT TO USE DUE TO COMPLEXITY 69 | 70 | // Initializes dramMatrix 71 | dramMatrix* createDRAMmatrix(int frameCount, int frameSize) 72 | { 73 | dramMatrix* M = malloc(sizeof(dramMatrix)); 74 | M->rowList = malloc(frameCount*sizeof(dramNode*)); 75 | M->columnList = malloc(frameSize*sizeof(dramNode*)); 76 | M->rows = frameCount; 77 | M->columns = frameSize; 78 | M->freeFrame = 0; 79 | 80 | // If there is not enough memory to make call to malloc(), we must free memory 81 | if(M == NULL || M->rowList == NULL || M->columnList == NULL) { 82 | printf("Error - Could not allocate a new Physical Memory Matrix!\n"); 83 | free(M); 84 | } 85 | 86 | return M; 87 | } 88 | 89 | */ 90 | /* 91 | Creating simulated physical memory space 92 | 93 | @Param {frameCount} The number of frames we want to represent in physical memory 94 | @Param {blockSize} The number of offsets we want per physical memory frame 95 | @Return {int**} The dynamically allocated physical memory space 96 | */ 97 | int** dramAllocate(int frameCount, int blockSize) 98 | { 99 | int** temp; 100 | temp = malloc(frameCount * sizeof(int*)); 101 | for(int i = 0; i < frameCount; i++) { 102 | temp[i] = (int*)malloc(sizeof(int) * blockSize); 103 | for(int j = 0; j < blockSize; j++) { 104 | temp[i][j] = 0; 105 | } 106 | } 107 | // If there is not enough memory to make call to malloc() // Notify and exit 108 | if(temp == NULL) { 109 | printf("Error - Could not allocate a new Physical Memory Matrix using dramAllocate() function!\r\n"); 110 | exit(-1); 111 | } 112 | return temp; 113 | } 114 | /* 115 | Will free dram memory after usage 116 | 117 | @Param {dblPtrArr} The physical memory we want to clear 118 | @Param {frameCount} The number of frames in the specified physical memory 119 | */ 120 | void freeDRAM(int*** dblPtrArr, int frameCount) 121 | { 122 | for (int i = 0; i < frameCount; i++) { 123 | if ((*dblPtrArr)[i] != NULL) { 124 | free((*dblPtrArr)[i]); 125 | } 126 | } 127 | free(*dblPtrArr); 128 | } 129 | 130 | /* 131 | 32-Bit masking function to extract page number 132 | This function assumes a high order page number and 133 | a low order page offset 134 | 135 | @Param {mask} The int masking value we will use to perform AND operation w.r.t. value 136 | @Param {value} The int value we wish to mask 137 | @Param {shift} The relative number of bits we want to shift right after the bitwise operation 138 | @Return {int} The int representation for Page Number 139 | */ 140 | int getPageNumber(int mask, int value, int shift) { 141 | return ((value & mask)>>shift); 142 | } 143 | 144 | /* 145 | 32-Bit masking function to extract physical memory offset 146 | This function assumes a high order page number and 147 | a low order page offset 148 | 149 | @Param {mask} The int masking value we will use to perform AND operation w.r.t. value 150 | @Param {value} The int value we wish to mask 151 | @Return {int} The int representation for physical memory offset 152 | */ 153 | int getOffset(int mask, int value) { 154 | return value & mask; 155 | } 156 | -------------------------------------------------------------------------------- /vmtypes.h: -------------------------------------------------------------------------------- 1 | #ifndef VMTYPES_H_ /* Include guard */ 2 | #define VMTYPES_H_ 3 | 4 | /* 5 | Defines a Virtual Memory Addressing table that can be 6 | represented as either a TLB cache or Page Table 7 | */ 8 | typedef struct vmTable_t { 9 | int *pageNumArr; // page number array 10 | int *frameNumArr; // frame number array for this 11 | int *entryAgeArr; // Age of each index 12 | int length; 13 | int pageFaultCount; 14 | int tlbHitCount; 15 | int tlbMissCount; 16 | } vmTable_t; 17 | 18 | 19 | /* 20 | The dramNode is used to form nodes in a linked list 21 | where each linked list represents phyical memory offset values. 22 | As with the other structs in this file, it is self-referential, but this 23 | struct is intended to be used as a component of the dramMatrix below to 24 | create a sparse matrix. 25 | */ 26 | /* DECIDED NOT TO USE -- Too Complex to Implement, but keeping JIC I want to use/fix later 27 | typedef struct dramNode { 28 | int row, column, 29 | int value; 30 | struct dramNode* rowPtr; 31 | struct dramNode* colPtr; 32 | } dramNode; 33 | */ 34 | /* 35 | The matrix component of the physical memory data structure is a struct that contains 36 | two arrays of dramNode pointers, each pointing to the first element in a row 37 | or column. The overall matrix is stored in a structure as follows and is 38 | implemented as an array of linked lists: 39 | 40 | ************* ************************* 41 | * rowList * ----------> * m * 42 | ************* ************************* 43 | * columnList* | 44 | ************* | 45 | | | 46 | v v 47 | ***** ***************** 48 | * * * * 49 | * *---------------------> * dramNode * 50 | * n * * * 51 | * * ***************** 52 | ***** 53 | */ 54 | 55 | /* DECIDED NOT TO USE -- Too Complex to Implement, but keeping JIC I want to use/fix later 56 | typedef struct dramMatrix { 57 | dramNode** rowList; // rowList is a pointer to the array of rows 58 | dramNode** columnList; // column list is a pointer to the array of columns. 59 | int rows, columns; // store the number of rows and columns of the matrix 60 | int freeFrame; // The first usable frame in physical memory--initially 0 61 | } dramMatrix; 62 | */ 63 | 64 | // This function creates a new Virtual Memory Table for 65 | // Logical address referencing -- Can represent either the TLB or Page Table Cache 66 | vmTable_t* createVMtable(int length); 67 | 68 | // This function prints contents of the vmTable 69 | void displayTable(vmTable_t** tableToView); 70 | 71 | /* DECIDED NOT TO USE -- Too Complex to Implement, but keeping JIC I want to use/fix later 72 | // This function creates a physical memory sparse matrix 73 | dramMatrix* createDRAMmatrix(int frameCount, int frameSize); 74 | */ 75 | // This function frees dynamically allocated memory 76 | void freeVMtable(vmTable_t** table); 77 | 78 | // Accepts an int double pointer for creating simulated physical memory space 79 | int** dramAllocate(int frameCount, int blockSize); 80 | 81 | // Will free dram memory after usage 82 | void freeDRAM(int*** dblPtrArr, int frameCount); 83 | 84 | 85 | // 32-Bit masking function to extract page number 86 | int getPageNumber(int mask, int value, int shift); 87 | 88 | // 32-Bit masking function to extract page offset 89 | int getOffset(int mask, int value); 90 | 91 | 92 | #endif // VMTYPES_H_ 93 | -------------------------------------------------------------------------------- /vmtypes.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedtran/VirtualMemoryManagementSim/f81c1efd1f1d447e4a1e1d285384d4cea63ee5e7/vmtypes.o --------------------------------------------------------------------------------