diff options
author | Karel Zak | 2006-12-07 00:25:32 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:32 +0100 |
commit | 6dbe3af945a63f025561abb83275cee9ff06c57b (patch) | |
tree | 19e59eac8ac465b5bc409b5adf815b582c92f633 /sys-utils/ipc.info | |
download | kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.gz kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.tar.xz kernel-qcow2-util-linux-6dbe3af945a63f025561abb83275cee9ff06c57b.zip |
Imported from util-linux-2.2 tarball.
Diffstat (limited to 'sys-utils/ipc.info')
-rw-r--r-- | sys-utils/ipc.info | 1106 |
1 files changed, 1106 insertions, 0 deletions
diff --git a/sys-utils/ipc.info b/sys-utils/ipc.info new file mode 100644 index 000000000..5d34e18df --- /dev/null +++ b/sys-utils/ipc.info @@ -0,0 +1,1106 @@ +This is Info file ipc.info, produced by Makeinfo-1.47 from the input +file ipc.texi. + + This file documents the System V style inter process communication +primitives available under linux. + + Copyright (C) 1992 krishna balasubramanian + + Permission is granted to use this material and the accompanying +programs within the terms of the GNU GPL. + + +File: ipc.info, Node: top, Next: Overview, Prev: Notes, Up: (dir) + +System V IPC. +************* + + These facilities are provided to maintain compatibility with +programs developed on system V unix systems and others that rely on +these system V mechanisms to accomplish inter process communication +(IPC). + + The specifics described here are applicable to the Linux +implementation. Other implementations may do things slightly +differently. + +* Menu: + +* Overview:: What is system V ipc? Overall mechanisms. +* Messages:: System calls for message passing. +* Semaphores:: System calls for semaphores. +* Shared Memory:: System calls for shared memory access. +* Notes:: Miscellaneous notes. + + +File: ipc.info, Node: Overview, Next: example, Prev: top, Up: top + +Overview +======== + +System V IPC consists of three mechanisms: + + * Messages : exchange messages with any process or server. + + * Semaphores : allow unrelated processes to synchronize execution. + + * Shared memory : allow unrelated processes to share memory. + +* Menu: + +* example:: Using shared memory. +* perms:: Description of access permissions. +* syscalls:: Overview of ipc system calls. + + Access to all resources is permitted on the basis of permissions set +up when the resource was created. + + A resource here consists of message queue, a semaphore set (array) +or a shared memory segment. + + A resource must first be allocated by a creator before it is used. +The creator can assign a different owner. After use the resource must +be explicitly destroyed by the creator or owner. + + A resource is identified by a numeric ID. Typically a creator +defines a KEY that may be used to access the resource. The user process +may then use this KEY in the "get" system call to obtain the ID for the +corresponding resource. This ID is then used for all further access. A +library call "ftok" is provided to translate pathnames or strings to +numeric keys. + + There are system and implementation defined limits on the number and +sizes of resources of any given type. Some of these are imposed by the +implementation and others by the system administrator when configuring +the kernel (*Note msglimits::, *Note semlimits::, *Note shmlimits::). + + There is an `msqid_ds', `semid_ds' or `shmid_ds' struct associated +with each message queue, semaphore array or shared segment. Each ipc +resource has an associated `ipc_perm' struct which defines the creator, +owner, access perms ..etc.., for the resource. These structures are +detailed in the following sections. + + +File: ipc.info, Node: example, Next: perms, Prev: Overview, Up: Overview + +example +======= + + Here is a code fragment with pointers on how to use shared memory. +The same methods are applicable to other resources. + + In a typical access sequence the creator allocates a new instance of +the resource with the `get' system call using the IPC_CREAT flag. + +creator process: + #include <sys/shm.h> + int id; + key_t key; + char proc_id = 'C'; + int size = 0x5000; /* 20 K */ + int flags = 0664 | IPC_CREAT; /* read-only for others */ + + key = ftok ("~creator/ipckey", proc_id); + id = shmget (key, size, flags); + exit (0); /* quit leaving resource allocated */ + +Users then gain access to the resource using the same key. +Client process: + #include <sys/shm.h> + char *shmaddr; + int id; + key_t key; + char proc_id = 'C'; + + key = ftok ("~creator/ipckey", proc_id); + + id = shmget (key, 0, 004); /* default size */ + if (id == -1) + perror ("shmget ..."); + + shmaddr = shmat (id, 0, SHM_RDONLY); /* attach segment for reading */ + if (shmaddr == (char *) -1) + perror ("shmat ..."); + + local_var = *(shmaddr + 3); /* read segment etc. */ + + shmdt (shmaddr); /* detach segment */ + +When the resource is no longer needed the creator should remove it. +Creator/owner process 2: + key = ftok ("~creator/ipckey", proc_id) + id = shmget (key, 0, 0); + shmctl (id, IPC_RMID, NULL); + + +File: ipc.info, Node: perms, Next: syscalls, Prev: example, Up: Overview + +Permissions +=========== + + Each resource has an associated `ipc_perm' struct which defines the +creator, owner and access perms for the resource. + + struct ipc_perm + key_t key; /* set by creator */ + ushort uid; /* owner euid and egid */ + ushort gid; + ushort cuid; /* creator euid and egid */ + ushort cgid; + ushort mode; /* access modes in lower 9 bits */ + ushort seq; /* sequence number */ + + The creating process is the default owner. The owner can be +reassigned by the creator and has creator perms. Only the owner, +creator or super-user can delete the resource. + + The lowest nine bits of the flags parameter supplied by the user to +the system call are compared with the values stored in `ipc_perms.mode' +to determine if the requested access is allowed. In the case that the +system call creates the resource, these bits are initialized from the +user supplied value. + + As for files, access permissions are specified as read, write and +exec for user, group or other (though the exec perms are unused). For +example 0624 grants read-write to owner, write-only to group and +read-only access to others. + + For shared memory, note that read-write access for segments is +determined by a separate flag which is not stored in the `mode' field. +Shared memory segments attached with write access can be read. + + The `cuid', `cgid', `key' and `seq' fields cannot be changed by the +user. + + +File: ipc.info, Node: syscalls, Next: Messages, Prev: perms, Up: Overview + +IPC system calls +================ + + This section provides an overview of the IPC system calls. See the +specific sections on each type of resource for details. + + Each type of mechanism provides a "get", "ctl" and one or more "op" +system calls that allow the user to create or procure the resource +(get), define its behaviour or destroy it (ctl) and manipulate the +resources (op). + +The "get" system calls +---------------------- + + The `get' call typically takes a KEY and returns a numeric ID that +is used for further access. The ID is an index into the resource table. +A sequence number is maintained and incremented when a resource is +destroyed so that acceses using an obselete ID is likely to fail. + + The user also specifies the permissions and other behaviour +charecteristics for the current access. The flags are or-ed with the +permissions when invoking system calls as in: + msgflg = IPC_CREAT | IPC_EXCL | 0666; + id = msgget (key, msgflg); + + * `key' : IPC_PRIVATE => new instance of resource is initialized. + + * `flags' : + IPC_CREAT : resource created for KEY if it does not exist. + + IPC_CREAT | IPC_EXCL : fail if resource exists for KEY. + + * returns : an identifier used for all further access to the + resource. + + Note that IPC_PRIVATE is not a flag but a special `key' that ensures +(when the call is successful) that a new resource is created. + + Use of IPC_PRIVATE does not make the resource inaccessible to other +users. For this you must set the access permissions appropriately. + + There is currently no way for a process to ensure exclusive access +to a resource. IPC_CREAT | IPC_EXCL only ensures (on success) that a new +resource was initialized. It does not imply exclusive access. + +See Also : *Note msgget::, *Note semget::, *Note shmget::. + +The "ctl" system calls +---------------------- + + Provides or alters the information stored in the structure that +describes the resource indexed by ID. + + #include <sys/msg.h> + struct msqid_ds buf; + err = msgctl (id, IPC_STAT, &buf); + if (err) + !$#%* + else + printf ("creator uid = %d\n", buf.msg_perm.cuid); + .... + +Commands supported by all `ctl' calls: + * IPC_STAT : read info on resource specified by id into user + allocated buffer. The user must have read access to the resource. + + * IPC_SET : write info from buffer into resource data structure. The + user must be owner creator or super-user. + + * IPC_RMID : remove resource. The user must be the owner, creator or + super-user. + +The IPC_RMID command results in immediate removal of a message queue or +semaphore array. Shared memory segments however, are only destroyed +upon the last detach after IPC_RMID is executed. + + The `semctl' call provides a number of command options that allow +the user to determine or set the values of the semaphores in an array. + +See Also: *Note msgctl::, *Note semctl::, *Note shmctl::. + +The "op" system calls +--------------------- + + Used to send or receive messages, read or alter semaphore values, +attach or detach shared memory segments. The IPC_NOWAIT flag will cause +the operation to fail with error EAGAIN if the process has to wait on +the call. + +`flags' : IPC_NOWAIT => return with error if a wait is required. + +See Also: *Note msgsnd::,*Note msgrcv::,*Note semop::,*Note shmat::, +*Note shmdt::. + + +File: ipc.info, Node: Messages, Next: msgget, Prev: syscalls, Up: top + +Messages +======== + + A message resource is described by a struct `msqid_ds' which is +allocated and initialized when the resource is created. Some fields in +`msqid_ds' can then be altered (if desired) by invoking `msgctl'. The +memory used by the resource is released when it is destroyed by a +`msgctl' call. + + struct msqid_ds + struct ipc_perm msg_perm; + struct msg *msg_first; /* first message on queue (internal) */ + struct msg *msg_last; /* last message in queue (internal) */ + time_t msg_stime; /* last msgsnd time */ + time_t msg_rtime; /* last msgrcv time */ + time_t msg_ctime; /* last change time */ + struct wait_queue *wwait; /* writers waiting (internal) */ + struct wait_queue *rwait; /* readers waiting (internal) */ + ushort msg_cbytes; /* number of bytes used on queue */ + ushort msg_qnum; /* number of messages in queue */ + ushort msg_qbytes; /* max number of bytes on queue */ + ushort msg_lspid; /* pid of last msgsnd */ + ushort msg_lrpid; /* pid of last msgrcv */ + + To send or receive a message the user allocates a structure that +looks like a `msgbuf' but with an array `mtext' of the required size. +Messages have a type (positive integer) associated with them so that +(for example) a listener can choose to receive only messages of a given +type. + + struct msgbuf + long mtype; type of message (*Note msgrcv::). + char mtext[1]; message text .. why is this not a ptr? + + The user must have write permissions to send and read permissions to +receive messages on a queue. + + When `msgsnd' is invoked, the user's message is copied into an +internal struct `msg' and added to the queue. A `msgrcv' will then read +this message and free the associated struct `msg'. + +* Menu: + +* msgget:: +* msgsnd:: +* msgrcv:: +* msgctl:: +* msglimits:: Implementation defined limits. + + +File: ipc.info, Node: msgget, Next: msgsnd, Prev: Messages, Up: Messages + +msgget +------ + +A message queue is allocated by a msgget system call : + + msqid = msgget (key_t key, int msgflg); + + * `key': an integer usually got from `ftok()' or IPC_PRIVATE. + + * `msgflg': + IPC_CREAT : used to create a new resource if it does not + already exist. + + IPC_EXCL | IPC_CREAT : used to ensure failure of the call if + the resource already exists. + + rwxrwxrwx : access permissions. + + * returns: msqid (an integer used for all further access) on success. + -1 on failure. + + A message queue is allocated if there is no resource corresponding +to the given key. The access permissions specified are then copied into +the `msg_perm' struct and the fields in `msqid_ds' initialized. The +user must use the IPC_CREAT flag or key = IPC_PRIVATE, if a new +instance is to be allocated. If a resource corresponding to KEY already +exists, the access permissions are verified. + +Errors: +EACCES : (procure) Do not have permission for requested access. +EEXIST : (allocate) IPC_CREAT | IPC_EXCL specified and resource exists. +EIDRM : (procure) The resource was removed. +ENOSPC : All id's are taken (max of MSGMNI id's system-wide). +ENOENT : Resource does not exist and IPC_CREAT not specified. +ENOMEM : A new `msqid_ds' was to be created but ... nomem. + + +File: ipc.info, Node: msgsnd, Next: msgrcv, Prev: msgget, Up: Messages + +msgsnd +------ + + int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg); + + * `msqid' : id obtained by a call to msgget. + + * `msgsz' : size of msg text (`mtext') in bytes. + + * `msgp' : message to be sent. (msgp->mtype must be positive). + + * `msgflg' : IPC_NOWAIT. + + * returns : msgsz on success. -1 on error. + + The message text and type are stored in the internal `msg' +structure. `msg_cbytes', `msg_qnum', `msg_lspid', and `msg_stime' +fields are updated. Readers waiting on the queue are awakened. + +Errors: +EACCES : Do not have write permission on queue. +EAGAIN : IPC_NOWAIT specified and queue is full. +EFAULT : msgp not accessible. +EIDRM : The message queue was removed. +EINTR : Full queue ... would have slept but ... was interrupted. +EINVAL : mtype < 1, msgsz > MSGMAX, msgsz < 0, msqid < 0 or unused. +ENOMEM : Could not allocate space for header and text. + +File: ipc.info, Node: msgrcv, Next: msgctl, Prev: msgsnd, Up: Messages + +msgrcv +------ + + int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, + int msgflg); + + * msqid : id obtained by a call to msgget. + + * msgsz : maximum size of message to receive. + + * msgp : allocated by user to store the message in. + + * msgtyp : + 0 => get first message on queue. + + > 0 => get first message of matching type. + + < 0 => get message with least type which is <= abs(msgtyp). + + * msgflg : + IPC_NOWAIT : Return immediately if message not found. + + MSG_NOERROR : The message is truncated if it is larger than + msgsz. + + MSG_EXCEPT : Used with msgtyp > 0 to receive any msg except + of specified type. + + * returns : size of message if found. -1 on error. + + The first message that meets the `msgtyp' specification is +identified. For msgtyp < 0, the entire queue is searched for the +message with the smallest type. + + If its length is smaller than msgsz or if the user specified the +MSG_NOERROR flag, its text and type are copied to msgp->mtext and +msgp->mtype, and it is taken off the queue. + + The `msg_cbytes', `msg_qnum', `msg_lrpid', and `msg_rtime' fields +are updated. Writers waiting on the queue are awakened. + +Errors: +E2BIG : msg bigger than msgsz and MSG_NOERROR not specified. +EACCES : Do not have permission for reading the queue. +EFAULT : msgp not accessible. +EIDRM : msg queue was removed. +EINTR : msg not found ... would have slept but ... was interrupted. +EINVAL : msgsz > msgmax or msgsz < 0, msqid < 0 or unused. +ENOMSG : msg of requested type not found and IPC_NOWAIT specified. + + +File: ipc.info, Node: msgctl, Next: msglimits, Prev: msgrcv, Up: Messages + +msgctl +------ + + int msgctl (int msqid, int cmd, struct msqid_ds *buf); + + * msqid : id obtained by a call to msgget. + + * buf : allocated by user for reading/writing info. + + * cmd : IPC_STAT, IPC_SET, IPC_RMID (*Note syscalls::). + + IPC_STAT results in the copy of the queue data structure into the +user supplied buffer. + + In the case of IPC_SET, the queue size (`msg_qbytes') and the `uid', +`gid', `mode' (low 9 bits) fields of the `msg_perm' struct are set from +the user supplied values. `msg_ctime' is updated. + + Note that only the super user may increase the limit on the size of a +message queue beyond MSGMNB. + + When the queue is destroyed (IPC_RMID), the sequence number is +incremented and all waiting readers and writers are awakened. These +processes will then return with `errno' set to EIDRM. + +Errors: + +EPERM : Insufficient privilege to increase the size of the queue +(IPC_SET) or remove it (IPC_RMID). +EACCES : Do not have permission for reading the queue (IPC_STAT). +EFAULT : buf not accessible (IPC_STAT, IPC_SET). +EIDRM : msg queue was removed. +EINVAL : invalid cmd, msqid < 0 or unused. + + +File: ipc.info, Node: msglimits, Next: Semaphores, Prev: msgctl, Up: Messages + +Limis on Message Resources +-------------------------- + +Sizeof various structures: + msqid_ds 52 /* 1 per message queue .. dynamic */ + + msg 16 /* 1 for each message in system .. dynamic */ + + msgbuf 8 /* allocated by user */ + +Limits + * MSGMNI : number of message queue identifiers ... policy. + + * MSGMAX : max size of message. Header and message space allocated + on one page. MSGMAX = (PAGE_SIZE - sizeof(struct msg)). + Implementation maximum MSGMAX = 4080. + + * MSGMNB : default max size of a message queue ... policy. The + super-user can increase the size of a queue beyond MSGMNB by a + `msgctl' call. + +Unused or unimplemented: +MSGTQL max number of message headers system-wide. +MSGPOOL total size in bytes of msg pool. + + +File: ipc.info, Node: Semaphores, Next: semget, Prev: msglimits, Up: top + +Semaphores +========== + + Each semaphore has a value >= 0. An id provides access to an array +of `nsems' semaphores. Operations such as read, increment or decrement +semaphores in a set are performed by the `semop' call which processes +`nsops' operations at a time. Each operation is specified in a struct +`sembuf' described below. The operations are applied only if all of +them succeed. + + If you do not have a need for such arrays, you are probably better +off using the `test_bit', `set_bit' and `clear_bit' bit-operations +defined in <asm/bitops.h>. + + Semaphore operations may also be qualified by a SEM_UNDO flag which +results in the operation being undone when the process exits. + + If a decrement cannot go through, a process will be put to sleep on +a queue waiting for the `semval' to increase unless it specifies +IPC_NOWAIT. A read operation can similarly result in a sleep on a queue +waiting for `semval' to become 0. (Actually there are two queues per +semaphore array). + +A semaphore array is described by: + struct semid_ds + struct ipc_perm sem_perm; + time_t sem_otime; /* last semop time */ + time_t sem_ctime; /* last change time */ + struct wait_queue *eventn; /* wait for a semval to increase */ + struct wait_queue *eventz; /* wait for a semval to become 0 */ + struct sem_undo *undo; /* undo entries */ + ushort sem_nsems; /* no. of semaphores in array */ + +Each semaphore is described internally by : + struct sem + short sempid; /* pid of last semop() */ + ushort semval; /* current value */ + ushort semncnt; /* num procs awaiting increase in semval */ + ushort semzcnt; /* num procs awaiting semval = 0 */ + +* Menu: + +* semget:: +* semop:: +* semctl:: +* semlimits:: Limits imposed by this implementation. + + +File: ipc.info, Node: semget, Next: semop, Prev: Semaphores, Up: Semaphores + +semget +------ + +A semaphore array is allocated by a semget system call: + + semid = semget (key_t key, int nsems, int semflg); + + * `key' : an integer usually got from `ftok' or IPC_PRIVATE + + * `nsems' : + # of semaphores in array (0 <= nsems <= SEMMSL <= SEMMNS) + + 0 => dont care can be used when not creating the resource. If + successful you always get access to the entire array anyway. + + * semflg : + IPC_CREAT used to create a new resource + + IPC_EXCL used with IPC_CREAT to ensure failure if the + resource exists. + + rwxrwxrwx access permissions. + + * returns : semid on success. -1 on failure. + + An array of nsems semaphores is allocated if there is no resource +corresponding to the given key. The access permissions specified are +then copied into the `sem_perm' struct for the array along with the +user-id etc. The user must use the IPC_CREAT flag or key = IPC_PRIVATE +if a new resource is to be created. + +Errors: +EINVAL : nsems not in above range (allocate). +nsems greater than number in array (procure). +EEXIST : (allocate) IPC_CREAT | IPC_EXCL specified and resource exists. +EIDRM : (procure) The resource was removed. +ENOMEM : could not allocate space for semaphore array. +ENOSPC : No arrays available (SEMMNI), too few semaphores available +(SEMMNS). +ENOENT : Resource does not exist and IPC_CREAT not specified. +EACCES : (procure) do not have permission for specified access. + + +File: ipc.info, Node: semop, Next: semctl, Prev: semget, Up: Semaphores + +semop +----- + +Operations on semaphore arrays are performed by calling semop : + + int semop (int semid, struct sembuf *sops, unsigned nsops); + + * semid : id obtained by a call to semget. + + * sops : array of semaphore operations. + + * nsops : number of operations in array (0 < nsops < SEMOPM). + + * returns : semval for last operation. -1 on failure. + +Operations are described by a structure sembuf: + struct sembuf + ushort sem_num; /* semaphore index in array */ + short sem_op; /* semaphore operation */ + short sem_flg; /* operation flags */ + + The value `sem_op' is to be added (signed) to the current value +semval of the semaphore with index sem_num (0 .. nsems -1) in the set. +Flags recognized in sem_flg are IPC_NOWAIT and SEM_UNDO. + +Two kinds of operations can result in wait: + 1. If sem_op is 0 (read operation) and semval is non-zero, the process + sleeps on a queue waiting for semval to become zero or returns with + error EAGAIN if (IPC_NOWAIT | sem_flg) is true. + + 2. If (sem_op < 0) and (semval + sem_op < 0), the process either + sleeps on a queue waiting for semval to increase or returns with + error EAGAIN if (sem_flg & IPC_NOWAIT) is true. + + The array sops is first read in and preliminary checks performed on +the arguments. The operations are parsed to determine if any of them +needs write permissions or requests an undo operation. + + The operations are then tried and the process sleeps if any operation +that does not specify IPC_NOWAIT cannot go through. If a process sleeps +it repeats these checks on waking up. If any operation that requests +IPC_NOWAIT, cannot go through at any stage, the call returns with errno +set to EAGAIN. + + Finally, operations are committed when all go through without an +intervening sleep. Processes waiting on the zero_queue or +increment_queue are awakened if any of the semval's becomes zero or is +incremented respectively. + +Errors: +E2BIG : nsops > SEMOPM. +EACCES : Do not have permission for requested (read/alter) access. +EAGAIN : An operation with IPC_NOWAIT specified could not go through. +EFAULT : The array sops is not accessible. +EFBIG : An operation had semnum >= nsems. +EIDRM : The resource was removed. +EINTR : The process was interrupted on its way to a wait queue. +EINVAL : nsops is 0, semid < 0 or unused. +ENOMEM : SEM_UNDO requested. Could not allocate space for undo +structure. +ERANGE : sem_op + semval > SEMVMX for some operation. + + +File: ipc.info, Node: semctl, Next: semlimits, Prev: semop, Up: Semaphores + +semctl +------ + + int semctl (int semid, int semnum, int cmd, union semun arg); + + * semid : id obtained by a call to semget. + + * cmd : + GETPID return pid for the process that executed the last + semop. + + GETVAL return semval of semaphore with index semnum. + + GETNCNT return number of processes waiting for semval to + increase. + + GETZCNT return number of processes waiting for semval to + become 0 + + SETVAL set semval = arg.val. + + GETALL read all semval's into arg.array. + + SETALL set all semval's with values given in arg.array. + + * returns : 0 on success or as given above. -1 on failure. + + The first 4 operate on the semaphore with index semnum in the set. +The last two operate on all semaphores in the set. + + `arg' is a union : + union semun + int val; value for SETVAL. + struct semid_ds *buf; buffer for IPC_STAT and IPC_SET. + ushort *array; array for GETALL and SETALL + + * IPC_SET, SETVAL, SETALL : sem_ctime is updated. + + * SETVAL, SETALL : Undo entries are cleared for altered semaphores in + all processes. Processes sleeping on the wait queues are awakened + if a semval becomes 0 or increases. + + * IPC_SET : sem_perm.uid, sem_perm.gid, sem_perm.mode are updated + from user supplied values. + +Errors: + +EACCES : do not have permission for specified access. +EFAULT : arg is not accessible. +EIDRM : The resource was removed. +EINVAL : semid < 0 or semnum < 0 or semnum >= nsems. +EPERM : IPC_RMID, IPC_SET ... not creator, owner or super-user. +ERANGE : arg.array[i].semval > SEMVMX or < 0 for some i. + + +File: ipc.info, Node: semlimits, Next: Shared Memory, Prev: semctl, Up: Semaphores + +Limits on Semaphore Resources +----------------------------- + +Sizeof various structures: + semid_ds 44 /* 1 per semaphore array .. dynamic */ + sem 8 /* 1 for each semaphore in system .. dynamic */ + sembuf 6 /* allocated by user */ + sem_undo 20 /* 1 for each undo request .. dynamic */ + +Limits : + * SEMVMX 32767 semaphore maximum value (short). + + * SEMMNI number of semaphore identifiers (or arrays) system + wide...policy. + + * SEMMSL maximum number of semaphores per id. 1 semid_ds per + array, 1 struct sem per semaphore => SEMMSL = (PAGE_SIZE - + sizeof(semid_ds)) / sizeof(sem). Implementation maximum SEMMSL = + 500. + + * SEMMNS maximum number of semaphores system wide ... policy. + Setting SEMMNS >= SEMMSL*SEMMNI makes it irrelevent. + + * SEMOPM Maximum number of operations in one semop + call...policy. + +Unused or unimplemented: +SEMAEM adjust on exit max value. +SEMMNU number of undo structures system-wide. +SEMUME maximum number of undo entries per process. + + +File: ipc.info, Node: Shared Memory, Next: shmget, Prev: semlimits, Up: top + +Shared Memory +============= + + Shared memory is distinct from the sharing of read-only code pages or +the sharing of unaltered data pages that is available due to the +copy-on-write mechanism. The essential difference is that the shared +pages are dirty (in the case of Shared memory) and can be made to +appear at a convenient location in the process' address space. + +A shared segment is described by : + struct shmid_ds + struct ipc_perm shm_perm; + int shm_segsz; /* size of segment (bytes) */ + time_t shm_atime; /* last attach time */ + time_t shm_dtime; /* last detach time */ + time_t shm_ctime; /* last change time */ + ulong *shm_pages; /* internal page table */ + ushort shm_cpid; /* pid, creator */ + ushort shm_lpid; /* pid, last operation */ + short shm_nattch; /* no. of current attaches */ + + A shmget allocates a shmid_ds and an internal page table. A shmat +maps the segment into the process' address space with pointers into the +internal page table and the actual pages are faulted in as needed. The +memory associated with the segment must be explicitly destroyed by +calling shmctl with IPC_RMID. + +* Menu: + +* shmget:: +* shmat:: +* shmdt:: +* shmctl:: +* shmlimits:: Limits imposed by this implementation. + + +File: ipc.info, Node: shmget, Next: shmat, Prev: Shared Memory, Up: Shared Memory + +shmget +------ + +A shared memory segment is allocated by a shmget system call: + + int shmget(key_t key, int size, int shmflg); + + * key : an integer usually got from `ftok' or IPC_PRIVATE + + * size : size of the segment in bytes (SHMMIN <= size <= SHMMAX). + + * shmflg : + IPC_CREAT used to create a new resource + + IPC_EXCL used with IPC_CREAT to ensure failure if the + resource exists. + + rwxrwxrwx access permissions. + + * returns : shmid on success. -1 on failure. + + A descriptor for a shared memory segment is allocated if there isn't +one corresponding to the given key. The access permissions specified are +then copied into the `shm_perm' struct for the segment along with the +user-id etc. The user must use the IPC_CREAT flag or key = IPC_PRIVATE +to allocate a new segment. + + If the segment already exists, the access permissions are verified, +and a check is made to see that it is not marked for destruction. + + `size' is effectively rounded up to a multiple of PAGE_SIZE as shared +memory is allocated in pages. + +Errors: +EINVAL : (allocate) Size not in range specified above. +(procure) Size greater than size of segment. +EEXIST : (allocate) IPC_CREAT | IPC_EXCL specified and resource exists. +EIDRM : (procure) The resource is marked destroyed or was removed. +ENOSPC : (allocate) All id's are taken (max of SHMMNI id's system-wide). +Allocating a segment of the requested size would exceed the system wide +limit on total shared memory (SHMALL). +ENOENT : (procure) Resource does not exist and IPC_CREAT not specified. +EACCES : (procure) Do not have permission for specified access. +ENOMEM : (allocate) Could not allocate memory for shmid_ds or pg_table. + + +File: ipc.info, Node: shmat, Next: shmdt, Prev: shmget, Up: Shared Memory + +shmat +----- + +Maps a shared segment into the process' address space. + + char *virt_addr; + virt_addr = shmat (int shmid, char *shmaddr, int shmflg); + + * shmid : id got from call to shmget. + + * shmaddr : requested attach address. + If shmaddr is 0 the system finds an unmapped region. + If a non-zero value is indicated the value must be page + aligned or the user must specify the SHM_RND flag. + + * shmflg : + SHM_RDONLY : request read-only attach. + SHM_RND : attach address is rounded DOWN to a multiple of SHMLBA. + + * returns: virtual address of attached segment. -1 on failure. + + When shmaddr is 0, the attach address is determined by finding an +unmapped region in the address range 1G to 1.5G, starting at 1.5G and +coming down from there. The algorithm is very simple so you are +encouraged to avoid non-specific attaches. + +Algorithm: + Determine attach address as described above. + Check region (shmaddr, shmaddr + size) is not mapped and allocate + page tables (undocumented SHM_REMAP flag!). + Map the region by setting up pointers into the internal page table. + Add a descriptor for the attach to the task struct for the process. + `shm_nattch', `shm_lpid', `shm_atime' are updated. + +Notes: +The `brk' value is not altered. The segment is automatically detached +when the process exits. The same segment may be attached as read-only +or read-write and more than once in the process' address space. A +shmat can succeed on a segment marked for destruction. The request for +a particular type of attach is made using the SHM_RDONLY flag. There is +no notion of a write-only attach. The requested attach permissions +must fall within those allowed by `shm_perm.mode'. + +Errors: +EACCES : Do not have permission for requested access. +EINVAL : shmid < 0 or unused, shmaddr not aligned, attach at brk failed. +EIDRM : resource was removed. +ENOMEM : Could not allocate memory for descriptor or page tables. + + +File: ipc.info, Node: shmdt, Next: shmctl, Prev: shmat, Up: Shared Memory + +shmdt +----- + + int shmdt (char *shmaddr); + + * shmaddr : attach address of segment (returned by shmat). + + * returns : 0 on success. -1 on failure. + + An attached segment is detached and `shm_nattch' decremented. The +occupied region in user space is unmapped. The segment is destroyed if +it is marked for destruction and `shm_nattch' is 0. `shm_lpid' and +`shm_dtime' are updated. + +Errors: +EINVAL : No shared memory segment attached at shmaddr. + + +File: ipc.info, Node: shmctl, Next: shmlimits, Prev: shmdt, Up: Shared Memory + +shmctl +------ + +Destroys allocated segments. Reads/Writes the control structures. + + int shmctl (int shmid, int cmd, struct shmid_ds *buf); + + * shmid : id got from call to shmget. + + * cmd : IPC_STAT, IPC_SET, IPC_RMID (*Note syscalls::). + IPC_SET : Used to set the owner uid, gid, and shm_perms.mode + field. + + IPC_RMID : The segment is marked destroyed. It is only + destroyed on the last detach. + + IPC_STAT : The shmid_ds structure is copied into the user + allocated buffer. + + * buf : used to read (IPC_STAT) or write (IPC_SET) information. + + * returns : 0 on success, -1 on failure. + + The user must execute an IPC_RMID shmctl call to free the memory +allocated by the shared segment. Otherwise all the pages faulted in +will continue to live in memory or swap. + +Errors: +EACCES : Do not have permission for requested access. +EFAULT : buf is not accessible. +EINVAL : shmid < 0 or unused. +EIDRM : identifier destroyed. +EPERM : not creator, owner or super-user (IPC_SET, IPC_RMID). + + +File: ipc.info, Node: shmlimits, Next: Notes, Prev: shmctl, Up: Shared Memory + +Limits on Shared Memory Resources +--------------------------------- + +Limits: + * SHMMNI max num of shared segments system wide ... 4096. + + * SHMMAX max shared memory segment size (bytes) ... 4M + + * SHMMIN min shared memory segment size (bytes). 1 byte (though + PAGE_SIZE is the effective minimum size). + + * SHMALL max shared mem system wide (in pages) ... policy. + + * SHMLBA segment low boundary address multiple. Must be page + aligned. SHMLBA = PAGE_SIZE. + +Unused or unimplemented: +SHMSEG : maximum number of shared segments per process. + + +File: ipc.info, Node: Notes, Next: top, Prev: shmlimits, Up: top + +Miscellaneous Notes +=================== + + The system calls are mapped into one -- `sys_ipc'. This should be +transparent to the user. + +Semaphore `undo' requests +------------------------- + + There is one sem_undo structure associated with a process for each +semaphore which was altered (with an undo request) by the process. +`sem_undo' structures are freed only when the process exits. + + One major cause for unhappiness with the undo mechanism is that it +does not fit in with the notion of having an atomic set of operations +on an array. The undo requests for an array and each semaphore therein +may have been accumulated over many `semop' calls. Thus use the undo +mechanism with private semaphores only. + + Should the process sleep in `exit' or should all undo operations be +applied with the IPC_NOWAIT flag in effect? Currently those undo +operations which go through immediately are applied and those that +require a wait are ignored silently. + +Shared memory, `malloc' and the `brk'. +-------------------------------------- + + Note that since this section was written the implementation was +changed so that non-specific attaches are done in the region 1G - 1.5G. +However much of the following is still worth thinking about so I left +it in. + + On many systems, the shared memory is allocated in a special region +of the address space ... way up somewhere. As mentioned earlier, this +implementation attaches shared segments at the lowest possible address. +Thus if you plan to use `malloc', it is wise to malloc a large space +and then proceed to attach the shared segments. This way malloc sets +the brk sufficiently above the region it will use. + + Alternatively you can use `sbrk' to adjust the `brk' value as you +make shared memory attaches. The implementation is not very smart about +selecting attach addresses. Using the system default addresses will +result in fragmentation if detaches do not occur in the reverse +sequence as attaches. + + Taking control of the matter is probably best. The rule applied is +that attaches are allowed in unmapped regions other than in the text +space (see <a.out.h>). Also remember that attach addresses and segment +sizes are multiples of PAGE_SIZE. + + One more trap (I quote Bruno on this). If you use malloc() to get +space for your shared memory (ie. to fix the `brk'), you must ensure you +get an unmapped address range. This means you must mallocate more memory +than you had ever allocated before. Memory returned by malloc(), used, +then freed by free() and then again returned by malloc is no good. +Neither is calloced memory. + + Note that a shared memory region remains a shared memory region until +you unmap it. Attaching a segment at the `brk' and calling malloc after +that will result in an overlap of what malloc thinks is its space with +what is really a shared memory region. For example in the case of a +read-only attach, you will not be able to write to the overlapped +portion. + +Fork, exec and exit +------------------- + + On a fork, the child inherits attached shared memory segments but +not the semaphore undo information. + + In the case of an exec, the attached shared segments are detached. +The sem undo information however remains intact. + + Upon exit, all attached shared memory segments are detached. The +adjust values in the undo structures are added to the relevant semvals +if the operations are permitted. Disallowed operations are ignored. + +Other Features +-------------- + + These features of the current implementation are likely to be +modified in the future. + + The SHM_LOCK and SHM_UNLOCK flag are available (super-user) for use +with the `shmctl' call to prevent swapping of a shared segment. The user +must fault in any pages that are required to be present after locking +is enabled. + + The IPC_INFO, MSG_STAT, MSG_INFO, SHM_STAT, SHM_INFO, SEM_STAT, +SEMINFO `ctl' calls are used by the `ipcs' program to provide +information on allocated resources. These can be modified as needed or +moved to a proc file system interface. + + Thanks to Ove Ewerlid, Bruno Haible, Ulrich Pegelow and Linus +Torvalds for ideas, tutorials, bug reports and fixes, and merriment. +And more thanks to Bruno. + + + +Tag Table: +Node: top349 +Node: Overview1049 +Node: example2881 +Node: perms4383 +Node: syscalls5943 +Node: Messages9392 +Node: msgget11426 +Node: msgsnd12810 +Node: msgrcv13778 +Node: msgctl15477 +Node: msglimits16684 +Node: Semaphores17558 +Node: semget19517 +Node: semop21060 +Node: semctl23624 +Node: semlimits25383 +Node: Shared Memory26523 +Node: shmget28008 +Node: shmat29803 +Node: shmdt31851 +Node: shmctl32383 +Node: shmlimits33514 +Node: Notes34161 + +End Tag Table |