
 The kernel part of DIPC intercepts the system calls that have to be 
handled differently, and delivers them to the user space part for further
processing, by placing the requests in a linked list, where they can later
be found by dipcd. It resides mainly in System V IPC source files, located
in the linux/ipc directory. But some files in other directories are also
affected. The file linux/arch/i386/mm/fault.c, which handles memory faults,
such as for reading a swapped out memory location, is one of them.

 The changes done to all these files were to enable DIPC to recognize the
cases in which it should take some action. When a distributed IPC structure
is created, some flags are used to note it in the structure itself. IPC_DIPC
is among these flags. Many other places will check for this flag and call
DIPC routines to handle a situation, if the need arises. Another flag
(DIPC_OWN) is used to note the fact that an IPC structure with a certain
key is the first one created in the cluster, that is, it is in the owner 
computer. This is tested to find out if an operation should be done locally 
or not. Operation on IPC structures that are in their owner computers
are done by normal IPC routines. 

 The flags mentioned above are invisible to the rest of the kernel. Only
DIPC kernel parts check them and take appropriate action based on their
values. This is the way the new functionalities of DIPC are integrated with
the rest of the system. 

 Management of distributed shared memories are done by using some structures 
inside the kernel. An array is setup for each shared memory segment, with a 
byte for every page of the segment. The state of the page, that is, whether
it is readable or writable, is noted in this byte. This method requires the
least amount of change to other parts of the kernel memory management
sources.

 dipcd registers itself with the kernel at the time it starts execution.
DIPC kernel parts will then recognize this process and treat it and its
children and grand children (three generations) specially. The reason for 
considering 3 generations is that a worker process is the grand child of the 
dipcd (or the back_end process) program, and it needs special privileges.

 DIPC can not work without the user space part, so it will just do nothing
when this process is not running, leaving original IPC routines to handle
things. 

 For structures who's owner is not the current computer, DIPC keeps a linked
list of owner addresses in the kernel. This linked list is searched for the
network address of the computer that should be the host of a remote action,
like Remote Procedure Calls. The following algorithm shows what happens.

Start
 1.If the request is for a failed commit then
  1.1 Delete the owner's network address.
 2.Initialize a request structure.
 3.Call the dipc_add_request routine.
 4.If the request is for deleting a structure then
  4.1 Delete the owner's network address.
 5.If the request is for searching for a structure then
 6.Add the owner's network address to the corresponding linked list.
End

 The next algorithm shows what happens in the dipc_add_request.
Start
 1.If the request is not to be handled by the referee then
  1.1 Find the owner's network address.
 2.Put the request in the linked list, to be found by dipcd.
 3.Sleep in the kernel till the results come back.
 4.Check for an interrupt, take the request out of the linked list and
   return
End

 The way the kernel parts communicate with the rest of DIPC is by a system
call, multiplexed with the rest of IPC system calls. This call is used for
some quite different purposes: getting commands, sending requests, or
reporting some status. Its declaration is

 int dipc(int first, int cmd, void *ptr).

 The first and the third parameters are used for different purposes. Their
use depends on the second argument, which tells what the routine is supposed
to do. Ordinary user programs should not use this system call.

 
 
