# 2020 OS Project 2 - Synchronous Virtual Device
## Goal
* Learn the implementation of memory pages and different serial communication mechanisms, and compare the performance.
## Due Time
* 2020/06/24 23:59:59
## Problem
Internet of things (IoT) is a popular topic in recent years. It is the network of physical objects, such as devices, vehicles, buildings and other things. Through the network, we can integrate the data collected by these objects, to reach an improvement in traffic, logistics, medicine, geriatrics, crime prevention and many other areas, which presents a Smart City Framework. Performance is one of the most consideration in system, especially in real-time system. However, these “smart” objects, usually based on an embedded system, which has less resource to calculate large data. Therefore, we could transmit these data to servers for analyzing, and we would have to decide which I/O should we implement in the system to get better performance. In this project, we would like to study synchronization in communication through writing device drivers, and compare the performance of primitive (read/write) I/O and memory-mapped I/O.
## Project
Given partial sample codes of virtual IoT which can transmit the data through kernel socket (TCP) with synchronous file I/O, you are asked to compare the performance with another approach through memory-mapped I/O, using functions like mmap.
We simulate an application of IoT in a master-slave model. The slave device establishes a TCP connection to the master with the IP address set by the user program through ioctl, which present the server collecting the data from specific device. In contrast, the master device listens on a specific TCP port when the module is loaded into the kernel.
There are two user programs, one for accessing the slave device (slave side) and the other for accessing the master device (master side). For the slave-side program, it first uses ioctl to set the IP address of the master. It then receives the data from the slave device and writes all of them to the output file by the specified method. You should display the whole content of page descriptors of the mapped memory region in hexadecimal on the console after all data have been written. Similarly, the master-side program will read the input file by the specified method and send the data to the master device.
There are two kernel programs, one for receive the data from master device, and transmit to user program (slave side), one for receive the data from user program, and send to master device (master side).
Once the transmission has completed, the programs will show the total transmission time, measured from when the device is opened until the device is closed, and the size of the transferred file in both computers. All the parameters will be passed to programs through standard input.
For bonus, you should transmit the data through kernel socket with asynchronous I/O, and compare the performance. Or your own better idea such as many files in parameters.
## Program input
* The programs will get the input parameters from the standard input.
* For the slave-side program
* N - how many received file.
* L - location to place the received file. There are N Ls.
* M - method to write the file and the device. fcntl for file I/O and mmap for memory-mapped I/O.
* IP - IP address of the master.
* For the master-side program
* N - how many target file.
* L - location of target file. There are N Ls.
* M - method to read the target file and the device. fcntl for file I/O and mmap for memory-mapped I/O.
For example, parameters for the slave-side program using file I/O might look like this:
```
./slave 1 received_file fcntl 192.168.1.1
```
Parameters for the master-side program using memory-mapped I/O might look like this:
```
./master 2 target_file1 target_file2 mmap
```
[Sample code and sample input.](https://drive.google.com/file/d/1rpJnDB9VRxM0vm1dGkeyyWFSko_Mf0Ek/view?usp=sharing) We will give two sets of sample input. One set could be one very big file, one set has many small files with some others bigger than buffer. the parameters can have many files. You need to provide other files to demo.
You need to implement the input parameter. Sample input parameter above is for reference. You can design your own input parameter if you have better idea. Explain your design in the report and you will get bonus point.
## Program Output
* Once the file transmitted, show the total transmission time and File size.
* Time Size
* Time - the transmission time
* Size - the size of the transmitted data
Sample output from the command
```
Transmission time: xx ms, File size: xxx bytes
```
Sample output for the page descriptors 
## Environment
| Platform | OS | Programming Language | Machine |
| ------------------------------ | ----- | -------------------- | --------------- |
| A real or virtualized PC or NB.| Linux | C | try to find one |
## Grading
| Completeness of functionality | Stability | Report | Coding style | Bonus |
| ----------------------------- | --------- | ------ | ------------ | ----- |
| 50% | 25% | 20% | 5% | 10% |
* Late penalty is 10% per day. E.g. if 2 days late and with grade 90, the final grade will be 90 * 90% * 90% = 72.9.
* Please also describe your roles in your project (report).
## Submit
* 請每組開啓一個 github repository 來管理本份作業,並至 [表單](https://forms.gle/QuDkRdUMpk6oYJUK8) 中填寫 repository 的網址,助教將會下載該 repository 的內容進行評分。同時,遲交的天數也會以 repository 最晚 commit 的時間戳記來計算。 github repository 請盡量設成不公開,避免遭人抄襲。
* repository 中需有一份報告(命名爲 report.pdf),報告請包含
-1.設計(含說明自己程式的設計針對自己準備的測試檔設計的好處,我們期待有創意的方向,在好的設計的同時,越有自己的想法分數會越高,切勿抄襲他人想法)
-2.比較file I/O和memory-mapped I/O的結果與效能差異,並解釋
-3.組內分工表及分工比重,為個人分數的依據
-4.reference,說明程式碼的參考來源或與其他組別討論
* 原始碼(Makefile, *.c, *.h)也請置於 repository
* 輸入檔有2組範例測資及各組自己準備不同大小數量的測試檔來DEMO,都請置於 repository 中的 input資料夾,並說明自己針對這類檔案設計的好處,自己準備的測試檔不得和其他組別相同
* 創建一個 output資料夾,將執行後輸出的 output file 以及 Time Size 的結果分別置於其中,檔名要能分辨是 fcntl 和 mmap 的輸出結果,例如: fcntl_result.txt 、 mmap_result.txt 等等
* 由於疫情的關係無法現場DEMO,所以必須上傳總共五分鐘內的影片到demo的資料夾,影片內容需至少包含:
-1.file I/O
-2.memory-mapped I/O
各種條件執行的過程以及 Time Size 結果(從下指令到程式結束)以及用 diff 檢查輸出的檔案與一開始的輸入檔是否相同
* 最後,你的 repository 的目錄結構應該類似於:
repository
├── XX.c
├── XX.h
├── Makefile
├── report.pdf
├── input
├── output
├── demo
└── ...
## Hint
Supplmental information for this project: slides ([pptx](https://drive.google.com/file/d/1pBT-EU779h34hCe1lZdOFBTHiIG32eJd/view)|[pdf](https://drive.google.com/file/d/1RnUDNFKh4jpNXqluLl2BWqzmV5lBdjTe/view))
Char drivers (chapter 3), Linux Device Drivers, Third Edition (https://lwn.net/Kernel/LDD3/)
The system call mmap (http://man7.org/linux/man-pages/man2/mmap.2.html)
Page table management in Linux (https://www.kernel.org/doc/gorman/html/understand/understand006.html)
sample_code is update kernel to 2.6.
sample_code_for_ 4.14.25.zip is update kernel to 4.14.25.