nelk / kernel Goto Github PK
View Code? Open in Web Editor NEWSE350 OS kernel project.
SE350 OS kernel project.
When we allocate stack memory, we mark it as owned by the respective process, which means they will be able to release their own stack.
We should instead mark it as Kernel owned or define a stack constant or something.
The UART i-process uses interrupts for both the transmission and receiving of characters from the serial port. No polling or busy waiting strategies may be implemented. The UART i-process forwards characters (or commands) received to the KCD, and also responds to messages received from the CRT display process to transmit characters to the serial port.
As well, the UART i-process is used to provide debugging services which will be used during the demonstration. Upon receiving specific characters (hot keys - your choice, e.g., !) as input, the UART i-process will print the fol- lowing to the RTX system console:
Control is transferred to the RTX (the calling process voluntarily releases the processor). The invoking process remains ready to execute. Another process may possibly be selected for execution.
EOM.
The timer i-process is executed each time a hardware timer interrupt occurs. The timer i-process should handle the delivery of delayed send messages after the required time has expired.
Demo code is in the sound branch. Merge it in?
The RTX will support a message-based IPC discussed in lectures. Messages are carried in envelopes (memory blocks, see below) with a header which is less than 64 bytes. Two IPC primitives will be implemented. The two primitives are:
int send_message(int process_ID, void *MessageEnvelope)
Delivers to the destination process a message carried in the message envelope (a memory block). Changes the state of destination process to ready_to_execute if appropriate. The sending process is preempted if the receiving process was blocked waiting for a message and has higher priority, otherwise the sender continues executing. The header of the message will have the layout given in the course overheads. It also fills in the send- er_process_id and destination_process_id fields in the message envelope. The fields sender_process_id, desti- nation_process_id and message_type are all of type int. The sender fills in the message_type field of the message envelope before invoking the primitive.
void *receive_message(int *sender_ID)
This is a blocking receive. If there is a message waiting, a pointer to the message envelope containing it will be returned to the caller. If there is no such message, the calling process blocks and another process is selected for execution. The sender of the message is identified through sender_ID, unless it is NULL. Note the sender_ID is an output parameter and is not meant to filter which message to receive.
Null Process
This process runs as the lowest priority process (level 4) in the RTX.. The Null process is the only process assigned to level 4. Level 4 is basically a “hidden” priority level reserved for the Null process. This preserves the 4 levels of user priorities (levels 0, .. , 3). Process id 0 is reserved for the null process. Initially, the following pseudo code can be used to design your null process:
loop forever
release the processor
end loop
Once you have preemption working, then the “release the processor” line could be removed from the infinite loop.
To make the RTX more generally applicable, the RTX will be configured at initialization as specified in the RTX Configuration Table. This table has three sections:
Found when running memory muncher and releaseProcess.
When release process says "I am in control." the message is actually output in one of the memory muncher's outputs, with "control" at the end of it. Mem muncher overwrites the message somehow.
If a process sets a priority level, check if current process priority is lower than highest priority ready process. If it is, context switch to higher priority process.
Might be about Memory Management too.
We could potentially use the "other 32KB" on the board.
See http://mbed.org/forum/mbed/topic/3179/?page=1#comment-16243
We could use this area for stack space, so we can hand out bigger stack segments than 256 bytes.
One idea that I mentioned to @jonathanwei was that we can use another MemInfo instance to have a separate memory allocator instance responsible for allocating stack space (this btw, is why we refactor globals into parameters).
Please add the file. Thanks.
When fun process exists in the process table, holding "!" will cause all output to cease.
The memory allocator can be simplified (and enhanced) with a small API change. We simply need to drop the OOM API and instead write an non blocking version of "acquireMemoryBlock" that returns NULL instead of blocking. That function can trivially be unit tested, and we can write the blocking version in terms of it.
Additionally, it occurs to me that the OOM API is racy, and will probably screw up when interrupts and preemption is implemented.
%C
command has two parameters: %C process_id new_priority
where process_id and new_priority are integers.%C
command with illegal parameters will be ignored with an error message printed on the console.OUtput states as strings (and names?)
System processes are those processes needed by the system to perform basic services (scheduling and I/O). You will need to make your design choice to determine which system processes require privileged level and which system processes can run at unprivileged level.
The primitive returns a pointer to a memory block to the calling process. If no memory block is available, the calling process is blocked until a memory block becomes available. If several processes are waiting for a memory block and a block becomes available, the highest priority waiting process will get it.
If there's one block's worth of memory left between next available memory address and the last available memory address, the out of memory API returns that memory is available. However, that block might actually be reserved for an arena header, so this will occasionally return false incorrectly.
The system console is used for communication with the RTX and application processes. It consists of two devices: keyboard and CRT display. These two devices communicate serially with the microcomputer; using the receive and transmit lines of one of the two RS-232 ports.
The RTX will include two system processes, the Keyboard Command Decoder (KCD) process and the CRT Display process. These processes work in cooperation with the UART interrupt handler i-process.
This primitive returns the memory block to the RTX. If there are processes waiting for a block, the block is given to the highest priority process, which is then unblocked. The caller of this primitive never blocks, but could be preempted. Thus, it may affect the currently executing process
We never allocate the null process stack.
The system console is used for communication with the RTX and application processes. It consists of two devices: keyboard and CRT display. These two devices communicate serially with the microcomputer; using the receive and transmit lines of one of the two RS-232 ports.
The RTX will include two system processes, the Keyboard Command Decoder (KCD) process and the CRT Display process. These processes work in cooperation with the UART interrupt handler i-process.
int delayed_send(int process_ID, void *MessageEnvelope, int delay)
The invoking process does not block. The message (in the memory block pointed to by the second parameter) will be sent to the destination process (process_ID) after the expiration of the delay (timeout, given in millisec- ond units).
An important category of software tests are the stress tests. These tests seek to verify the behavior of the system under heavy stress scenarios. One such scenario is depletion (or near depletion) of system resources. For the demonstration of this project, you will implement three processes whose behavior is described below. The stress scenario being tested is depletion of memory blocks.
Process A:
p <- request_memory_block
register with Command Decoder as handler of %Z commands
loop forever
p <- receive a message
if the message(p) contains the %Z command then
release_memory_block(p)
exit the loop
else
release_memory_block(p)
endif
endloop
num = 0
loop forever
p <- request memory block to be used as a message envelope
set message_type field of p to “count_report”
set msg_data[0] field of p to num
send the message(p) to process B
num = num + 1
release_processor()
endloop
Process A does not de-allocate any received envelopes in the second loop
Process B:
loop forever
receive a message
send the message to process C
endloop
Process C:
perform any needed initialization and create a local message queue
loop forever
if (local message queue is empty) then
p <- receive a message
else
p <- dequeue the first message from the local message queue
endif
if msg_type of p == “count_report” then
if msg_data[0] of p is evenly divisible by 20 then
send "Process C" to CRT display using msg envelope p hibernate for 10 sec
endif
endif
deallocate message envelope p
release_processor()
endloop
The line “hibernate for 10 sec” is further expanded as:
q <- request_memory_block()
request a delayed_send for 10 sec delay with msg_type=wakeup10 using q
loop forever
p <- receive a message //block and let other processes execute
if (message_type of p == wakeup10) then
exit this loop
else
put message (p) on the local message queue for later processing
endif
endloop
Notes:
They must:
This primitive returns the priority of the process specified by the process_ID parameter. For an invalid process_ID, the primitive returns “-1”.
The demonstration of your working project will consist of two phases. In the first phase, initial manual testing will be performed using the specified keyboard commands without the testing processes you wrote. There should be exactly 32 memory blocks available to the user processes for this part of the demonstration.
In the second phase, you will be required to include the test processes (written by yourself, see section 4.3.4) in your RTX and execute the test sequence.
One requirement is that the six testing processes have reserved process ids 1, 2, 3, 4, 5 and 6. An overview of the expected mapping of process ids to processes is given in the table below:

Process_id
Owner Process


Process_id

Owner Process

0
Null process
6
Test_process_6

1
Test_process_1
7
Process A

2
Test_process_2
8
Process B

3
Test_process_3
9
Process C

4
Test_process_4
10...
Other processes start from pid 10

5

Test_process_5
...


Since the test processes have no knowledge of your detailed internal design, they only invoke the functions speci- fied by the RTX API. The test processes can use the timer that is not used by the RTX for timing testing. We require the testing results to follow the following format and you output the results to the HyperTerminal (i.e. UART0):
Gid_test: START
Gid_test: test n OK
Gid_test: test m FAIL
Gid_test: x/N tests OK
Gid_test: y/N tests FAIL
Gid_test: END
For example, if you are group G099 and you have 3 testing cases in total. Two of the testing cases pass and one of the testing cases does not pass. The final testing results should be output to HyperTerminal as follows:
G099_test: START
G099_test: total 3 tests
G099_test: test 1 OK
G099_test: test 2 OK
G099_test: test 3 FAIL
G099_test: 2/3 tests OK
G099_test: 1/3 tests FAIL
G099_test: END
Related to #105
bridge layer/etc
Maybe we want to make this a community-owned portion?
This process registers itself with the Keyboard Command Decoder process as the handler for the %W command.
The %WR command will reset the current wall clock time to 00:00:00, starts the clock running and causes
display of the current wall clock time on the console CRT. The display will be updated every second.
The %WS hh:mm:ss command sets the current wall clock time to hh:mm:ss, starts the clock running and causes display of the current wall clock time on the console CRT. The display will be updated every se- cond.
The %WT command will cause the wall clock display to be terminated.
A keyboard command starts with the prompt character %, followed by a single (or multiple) letter command identifier and possibly additional command data.
For example, %WS 12:45:00
could be a command to the wall clock process, telling it to start the wall clock display and setttig the current time to 12:45:00 (where the command format is %WS hh:mm:ss
).
The command decoder process responds to two types of messages: console keyboard input and command registration.
The latter contains the command identifier and the process id of the process to which such commands are to be delivered when entered on the console keyboard. The processing of messages received depends on their type:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.