alon7 / OS-hmwk2

Implemented a new system call, getting the process tree information

Home Page:http://www.cs.columbia.edu/~nieh/teaching/w4118/homeworks/hmwk2.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

----------------------
Solution to Question 4
----------------------
For a fancy version of our solution to Q4, please refer to Q4.pdf in the same directory.

Q4, a)Run your test program several times. Which fields in the prinfo structure change?
Which ones do not? Discuss why different fields might change with different frequency.

A:
The pid “prinfo” change each run. Because every time we use adb shell to create new instance of prinfo,
the new pid will be re-assigned to prinfo. And the prinfo is actually the child process of adbd.
So both child pid of adbd and pid of prinfo itself change.

Other fields don't change, because we never touch other programs.

Though it is expected to observe some of the "process state" changes, but
in the few run of our program, we didn't see state field change.


Q4, b)Start the mobile web browser in the emulator, and re-run your test program.
How many processes are started? What is/are the parent process(es) of the new process(es)?
Close the browser (press the "Home" button). How many processes were destroyed? Discuss your findings.

A: When we start the web browser, the android.browser process is created.
It’s child process of zygote. When close the browser(I mean go to app manage of Android to stop the browser),
the android.browser will be destroyed. If we tap the Home button instead, the android.browser still exists.
It may go to background mode, and later might be killed by android if resources are limited.

Q4, c)Notice that on the Android platform there is a process named zygote.
Investigate this process and any children processes:
i)What is the purpose of this process?

A:
Zygote is a daemon whose goal is to launch Apps, do the function similiar to fork().
Zygote is the parent of all App processes in android.

ii)Where is the zygote binary? If you can't find it,
how might you explain its presence in your list of processes?

There’s no independent zygote binary but zygote is started by /system/bin/app_process -Xzygote.
After kernel is loaded, init.rc is parsed and native services are started. With this, the /system/bin/app_process is run.
We can find some comments in app_process source(frameworks/base/cmds/app_process/app_main.cpp):
    // --zygote : Start in zygote mode
    // --start-system-server : Start the system server.
    // --application : Start in application (stand alone, non zygote) mode.
    // --nice-name : The nice name for this process.
    //
    // For non zygote starts, these arguments will be followed by
    // the main class name. All remaining arguments are passed to
    // the main method of this class.
    //
    // For zygote starts, all remaining arguments are passed to the zygote.
    // main function.

This eventually calls AndroidRuntime.start() function, passing it the parameters com.android.internal.os.ZygoteInit
and start-system-server. ZygoteInit.main() first registers the zygote socket.
It initializes a lot of classes system-wide resources like drawables, xmls, etc.
Then it calls startSystemServer() which forks a new process for com.android.server.SystemServer.
Zygote process opens a socket /dev/socket/zygote to listen for requests for starting applications.

iii)Discuss some reasons why an embedded system might choose to use a process like the zygote.
A:
1, To save time start other applications. Once Zygote starts, it preloads all necessary Java classes and resources,
starts System Server, initialize all the different System Services and the Activity Manager.
For System Service, we refer to the picture above. They are shared resources for other Apps.
So when launch app, there’s no need to start services again.

2, For the design pattern of android, zygote is to start Dalvik VM each time App launches.
This is different from the way linux do. So it’s necessary to take zygote the responsibility to manage all App processes.

3, Save memory. As we know, Android runs on Linux. The Linux Kernel implements a strategy call Copy On Write (COW).
In the case of Android those libraries are not writable. This means that all process forked from Zygote are using the exact same copy of the system classes and resources.
No matter how many applications are started the increase in memory usage will be a lot smaller.




--------------
Output Example
--------------
printf(/* correct number of \t */);
printf("%s,%d,%ld,%d,%d,%d,%d\n", p.comm, p.pid, p.state,
	 p.parent_pid, p.first_child_pid, p.next_sibling_pid, p.uid);

Example:

init,1,1,0,60,0,0
        ...
	 servicemanager,44,1,1,0,43,1000
	 vold,45,1,1,0,44,0
	 netd,47,1,1,0,45,0
	 debuggerd,48,1,1,0,47,0
	 rild,49,1,1,0,48,1001
	 surfaceflinger,50,1,1,0,49,1000
	 zygote,51,1,1,745,50,0
		  system_server,371,1,51,0,0,1000
                ...
		  android.launcher,530,1,51,0,517,10008

----------------
Prinfo Structure
----------------
struct prinfo {
	pid_t parent_pid;		/* process id of parent */
	pid_t pid;			/* process id */
	pid_t first_child_pid;  	/* pid of youngest child */
	pid_t next_sibling_pid;  	/* pid of older sibling */
	long state;			/* current state of process */
	long uid;			/* user id of process owner */
	char comm[64];			/* name of program executed */
};


--------------
Design Pattern
--------------
Function Hierachy

		|-------------------------|             |------------|
                |     dfs_prinfo_copy     |>------------|     dfs    |
                |-------------------------|             |------------|
                               \                           ^
                                \                         /
                                 \                       /
                                  \                     /
                                   \                   /
                                    \                 /
                                     \               /
                                      \             /
                                       \           /
                           |------------- SYSCALL_DEFINE2 --------------|



---------------
SYSCALL_DEFINE2
---------------
We find root first:

while (p->parent != NULL && p->parent->pid != 0
  && p->parent != p)
  p = p->parent;

Then we call dfs to search in a non-recursion way:

read_lock(&tasklist_lock);
dfs(p, kernel_buf, &copy_count, &pr_count, space_count);
read_unlock(&tasklist_lock);

---
dfs
---
For this function we do dfs in a non-recursion way.
Depth-first search (DFS) is an algorithm for
traversing or searching tree or graph data structures.

---------------
dfs_prinfo_copy
---------------
We copy all the essential data in this function,
in a DFS way.

About

Implemented a new system call, getting the process tree information

http://www.cs.columbia.edu/~nieh/teaching/w4118/homeworks/hmwk2.html


Languages

Language:C 95.9%Language:Assembly 1.9%Language:C++ 1.3%Language:Objective-C 0.3%Language:Makefile 0.3%Language:Perl 0.1%Language:Shell 0.0%Language:Python 0.0%Language:Bison 0.0%Language:TeX 0.0%Language:Awk 0.0%Language:Scilab 0.0%Language:UnrealScript 0.0%Language:Scala 0.0%Language:ASP 0.0%Language:XSLT 0.0%Language:Perl 6 0.0%Language:Prolog 0.0%Language:Vim Script 0.0%