0
7.7kviews
Manipulation of the Process Address Space
1 Answer
0
114views

The region table entry contains the following information:

  • The i-node of the file from which the region was initially loaded
  • The type of the region (text, shared memory, private data, or stack)
  • The size of the region
  • The location of the region in physical memory.
  • The state of the region: locked, in demand, being loaded into memory, valid, loaded into memory
  • The reference count, giving the number of processes that reference the region

The operations that manipulate regions are:

  • lock a region
  • unlock a region
  • allocate a region
  • attach a region to the memory space of a process
  • change the size of a region
  • load a region from a file into the memory space of a process
  • free a region
  • detach a region from the memory space of a process, and duplicate the contents of a region

Locking and Unlocking a Region

The kernel can lock and unlock a region independent of the operations to allocate and free a region, same as the locking-unlocking technic of i-nodes is independent of the allocating the releasing (iget and iput) inodes.

Allocating a Region

The kernel allocates a region when fork, exec, and shmget (shared memory get) system calls occurs. Just like i-nodes, the kernel has a free list of regions. When a region is to be allocated, the kernel picks up the first region from the free list and puts it on the active list. The i-node is used by the kernel to enable other processes to share the region. The kernel increments the i-node reference count to prevent other processes from removing its contents when unlinking it.

The pseudocode for allocreg is given below:

/* Algorithm: allocreg
* Input: inode pointer

* region type
* Output: locked region
*/
{
    remove region from linked list as a free regions;
    assign type of region;
    assign inode pointer region;
    if (inode pointer not null)
    increment inode reference count;
    put the region on linked list of active regions;
    return (locked region);
}

We have to make sure if the i-node pointer is not null because there are a few exceptions where a region is not associated with an i-node.

Attaching a Region to a Process

The kernel attaches the region to a process address space by using attachreg system call. It is used in fork, exec, and shmat. The region being attached may be newly allocated or already allocated region which is to be shared.

The algorithm is given below:

/* Algorithm: attachreg
* Input: pointer to (locked) region being attached
* process to which the region is being attached
* virtual address in process where region will be attached
* region type
* Output: pre process region table entry
*/
{
    allocate per process region table entry for process;
    initialize per process region table entry;
    set pointer to region being attached;
    set type field;
    set virtual address field;
    check legality of virtual address, region size;

    increment region reference count;
    increment process size according to attached region;
    initialize new hardware register triple for process;
    return (per process region table entry);
}

Changing the Size of a Region

The stack region can be changed (it can be expanded or shrunk) automatically when nesting of calls is done. It uses the growreg algorithm. The data region of a process can be expanded with the sbrk system call. It also internally calls growreg. Both of these regions are private to a process. Shared regions cannot be extended, so there are no side-effects of growreg.

The algorithm growreg is given below:

/* Algorithm: growreg
* Input: pointer to per process region table entry
* change in size of region (positive or negative)
* Output: none
*/
{
    if (region size increasing)
    {
        check new region size is legel ;
        allocate auxiliary tables (page tables);
        if (system unable to support demand paging)
        {
            assign a physical memory;
            initialize auxiliary tables, as necessary;
        }
    }
    else // region size decreasing
    {
        deallocate physical memory, as appropriate;
        free auxiliary tables, as appropriate;
    }
    do (other) initialization of auxiliary tables, as necessary;

    set size field in process table;
}

Loading a Region

If a system supports demand paging facility, the kernel can "map" a file into process address space when the exec system call is made. It then read individual physical pages later if necessary.

If the kernel does not support demand paging, it must copy the executable file into memory, loading the process regions at virtual addresses specified in the executable file. It may attach a region at a different virtual address from where it loads the contents of the file, creating a gap in the page table.

For example, this problem will become memory faults when user programs access address 0 illegally. Programs with pointer variables sometimes use them without checking that their value is 0 and, hence, that they are illegal for use as a pointer reference. By protecting the page containing address 0 appropriately, processes that errantly access address 0 incur a fault and abort, allowing programmers to discover such bugs more quickly.

The algorithm loadreg is given below:

/* Algorithm: loadreg
* Input: pointer to per process region table entry
* virtual address to load region
* inode pointer of file for loading region
* byte offset in file for start of region
* byte count for amount of data to load
* Output: none
*/
{
    expand region size to the max size of region (algorithm: growreg);
    mark region state: being loaded into memory;
    unlock region;
    set up u-area parameters for reading file:
    track virtual address where data is read to,
    start offset value for reading file,
    count of bytes to read from file;
    read file into region (internal variant of read algorithm);
    lock region;
    mark region state: completely loaded into memory;

    awaken all processes waiting for region to be loaded;
}

For example, if the kernel have to store text of size 7K into a region that is attached at virtual address 0 of a process but wants to leave a gap of 1K bytes at the beginning of the region. Now, the kernel will call the algorithm allocreg and allocate a region table entry.

Kernel also attaches the region at address 0 using algorithms attachreg. Now it invokes loadreg, which invokes growreg twice. It will leave 1K byte gap at the beginning of the region first, and second, to allocate storage for the contents of the region and growreg allocates a page table for the region. The kernel then sets up fields in the u-area to read the file: It reads 7K bytes from a specified byte offset in the file (supplies as a parameter by the kernel) into virtual address 1K of the process.

It is shown in the following diagram:

enter image description here

Freeing a Region

When a kernel no longer needs a region, it frees the region and places it on the free list again. The algorithm freereg is given below:

/* Algorithm: freereg
* Input: pointer to a (locked) region
* Output: nothing
*/
{
    if (region reference count not a zero)
    {
        // some process still using region

        release region lock;

        if (region has an associated inode)
        release inode lock;
        return;
    }
    if (region has associated inode)
    release inode (algorithm: iput);
    free physical memory still associated with region;
    free auxiliary tables associated with region;
    clear region fields;
    place region on region free list;
    unlock region;
}

Detaching a Region from a Process

The kernel detaches regions by the exec, exit, and shmdt system calls. It updates the pre-region entry and cancel the connection to physical memory by invalidating the associated memory management register triple.

The address translation mechanisms thus invalidated apply specifically to the process, not to the region (as in the algorithm freereg). The kernel decrements the region reference count. If the region referenced count drops to 0 and there is no reason to keep the region in memory, the kernel frees the region with algorithm freereg. Otherwise, it only releases the region and inode locks.

The algorithm detachreg is given below:

/* Algorithm: detachreg
* Input: pointer to per process region table entry
* Output: nothing
*/
{
    get auxiliary memory management tables for process, release as appropriate;
    decrement process size;
    decrement region reference count;
    if (region reference count is 0 and region not stick bit)
    free region (algorithm: freereg;)
    else // either reference count non-0 or region sticky bit on
    {
        free inode lock, if applicable (inode associated with region);
        free region lock;
    }
}

Duplicating a Region

In the fork system call, the kernel requires to duplicate the regions of a process. If the region is shared, the kernel just increments the reference count of the region. If it is not shared, the kernel has to physically copy it, so it allocates a new region table entry, page table, and physical memory for the region. The algorithm duplicate_reg is given below:

/* Algorithm: duplicate_reg
* Input: pointer to region table entry
* Output: pointer to a region that similar to input region
*/
{
    if (region type is shared)
    // caller will increment region reference count with attachreg call
    return (input region pointer);
    allocate new region (through the allocreg);

    set up auxiliary memory management structures, as currently exist in input
    region;
    allocate physical memory region contents;
    "copy" region contents from input region to newly allocated region;
    return (pointer to allocated region);
}

enter image description here

Sleep

Processes sleep inside of system calls awaiting for a particular resource or even if a page fault occurs. In such cases, they push a context layer and do a context switch. The context layers of a sleep process are shown below:

enter image description here

Please log in to add an answer.