Introduction
to System V IPC
933
3. The identifier for the IPC object is calculated using the following formula:
identifier = index + xxx_perm.__seq * SEQ_MULTIPLIER
In the formula used to calculate the IPC identifier, index is the index of this object
instance
within the entries array, and
SEQ_MULTIPLIER
is a constant defined with the
value 32,768 (
IPCMNI
in the kernel source file
include/linux/ipc.h
). For example,
in Figure 45-1, the identifier generated for the
semaphore with the key value
0x4b079002
would be (2 + 5 * 32,768) = 163,842.
Note the following points about the algorithm employed by the get calls:
z
Even if a new IPC object is created with the same key, it will almost certainly
have a different identifier, since the identifier is calculated based on the seq
value saved in
the associated data structure, and this value is incremented by
one during the creation of each object of this type.
The algorithm employed within the kernel wraps the seq value back to 0 when
it reaches the value
(INT_MAX
/
IPCMNI)
—that is, 2,147,483,647 / 32,768 = 65,535.
Thus, a new IPC object could have the same identifier
as a previous object if
65,535 objects are created in the interim and the new object reuses the same
element in the entries array as the previous object (i.e., this element must also
have been freed in the interim). However, the chances of this occurring are small.
z
The algorithm generates a distinct set of identifier
values for each index of the
entries array.
z
Since the constant
IPCMNI
defines an upper limit on the number of System V
objects of each type, the algorithm guarantees that
each existing IPC object has
a unique identifier.
z
Given an identifier value, the corresponding index into the entries array can be
quickly calculated using this equation:
index = identifier % SEQ_MULTIPLIER
Being able to rapidly perform this calculation is necessary for the efficient
operation of those IPC system calls that are supplied with the identifier of an
IPC object (i.e., those calls in Table 45-1 other than the get calls).
In passing, it is worth noting that two different errors can
result if a process makes
an IPC system call (e.g., msgctl(), semop(), or shmat()) that specifies an identifier that
doesn’t correspond to an existing object. If the corresponding index of entries is
empty, the
error
EINVAL
results. If the index points to an associated data structure,
but the sequence number stored in that structure doesn’t yield the same identifier
value, then it is assumed that an old object pointed to
by this array index has been
deleted and the index reused. This scenario is diagnosed with the error
EIDRM
.