Intro(PCI) 6 January 1993 Intro(PCI) Name Intro - introduction to message queues and semaphores Syntax This section describes message queues, semaphore permissions, and data structures. Description Message queue identifier A message queue identifier (msqid) is a unique positive integer created by a msgget system call. Each msqid has a message queue and a data struc- ture associated with it. The data structure is referred to as msqidds and contains the following members: struct ipc_perm msg_perm; /* operation permission struct */ time_t msg_stime; /* last msgsnd time */ time_t msg_rtime; /* last msgrcv time */ time_t msg_ctime; /* last change time */ /* Times measured in secs since */ /* 00:00:00 GMT, Jan. 1, 1970 */ ushort msg_cbytes; /* current number of bytes on q */ ushort msg_qnumn; /* number of msgs on q */ ushort msg_qbytes; /* max number of bytes on q */ ushort msg_lspid; /* pid of last msgsnd operation */ ushort msg_lrpid; /* pid of last msgrcv operation */ msgperm is an ipcperm structure that specifies the message operation permission (see below). This structure includes the following members: ushort uid; /* user ID */ ushort gid; /* group ID */ ushort cuid; /* creator user ID */ ushort cgid; /* creator group ID */ ushort mode; /* r/w permission */ ushort seq; /* slot usage sequence number */ key_t key; /* key */ msgstime is the time of the last msgsnd operation. msgrtime is the time of the last msgrcv operation. msgctime is the time of the last msgctl operation that changed a member of the above structure. msgcbytes is the number of bytes currently on the queue. msgqnum is the number of messages currently on the queue. msgqbytes is the maximum number of bytes allowed on the queue. msglspid is the process ID of the last pro- cess that performed a msgsnd operation. msglrpid is the process ID of the last process that performed a msgrcv operation. Message operation permissions In the msgctl, msgrcv, and msgsnd system call descriptions, the permis- sion required for an operation is given as "{token}", where token is the type of permission needed, interpreted as follows: 00400 Read by user 00200 Write by user 00040 Read by group 00020 Write by group 00004 Read by others 00002 Write by others Following usual UNIX operating system permission conventions, permissions can be combined. For example, 00600 means read and write by user; 00640 means read and write by user and read by group. Read and write permissions on an msqid are granted to a process if one or more of the following are true: + effective user ID of the process is super-user. + effective user ID of the process matches msgperm.[c]uid in the data structure associated with msqid, and the appropriate bit of the "user" portion (0600) of msgperm.mode is set. + effective user ID of the process does not match msgperm.[c]uid, and the effective group ID of the process matches msgperm.[c]gid, and the appropriate bit of the "group" portion (060) of msgperm.mode is set. + effective user ID of the process does not match msgperm.[c]uid, and the effective group ID of the process does not match msgperm.[c]gid, and the appropriate bit of the "other" portion (06) of msgperm.mode is set. Otherwise, the corresponding permissions are denied. Semaphore identifier A semaphore identifier (semid) is a unique positive integer created by a semget system call. Each semid has a set of semaphores and a data struc- ture associated with it. The data structure is referred to as semidds and contains the following members: struct ipc_perm sem_perm; /* operation permission struct */ time_t sem_otime; /* last operation time */ time_t sem_ctime; /* last change time */ /* Times measured in secs since */ /* 00:00:00 GMT, Jan. 1, 1970 */ ushort sem_nsems; /* number of sems in set */ semperm is an ipcperm structure that specifies the semaphore operation permission (see above). semnsems is equal to the number of semaphores in the set. Each sema- phore in the set is referenced by a positive integer referred to as a semnum. Semnum values run sequentially from 0 to the value of semnsems minus 1. semotime is the time of the last semop operation. semctime is the time of the last semctl operation that changed a member of the above structure. A semaphore is a data structure that contains the following members: ushort semval; /* semaphore value */ short sempid; /* pid of last operation */ ushort semncnt; /* # awaiting semval > cval */ ushort semzcnt; /* # awaiting semval = 0 */ semval is a nonnegative integer. sempid is equal to the process ID of the last process that performed a semaphore operation on this semaphore. semncnt is a count of the number of processes that are currently suspended awaiting this semaphore's semval to become greater than its current value. semzcnt is a count of the number of processes that are currently suspended awaiting this semaphore's semval to become zero. Semaphore operation permissions In the semop and semctl system call descriptions, the permission required for an operation is given as "{token}", where token is the type of per- mission needed, interpreted as follows: 00400 Read by user 00200 Alter by user 00040 Read by group 00020 Alter by group 00004 Read by others 00002 Alter by others Following usual UNIX operating system permission conventions, permissions can be combined. For example, 00600 means read and alter by user; 00640 means read and alter by user and read by group. Read and alter permissions on a semid are granted to a process if one or more of the following are true: + effective user ID of the process is super-user. + effective user ID of the process matches semperm.[c]uid in the data structure associated with semid, and the appropriate bit of the "user" portion (0600) of semperm.mode is set. + effective user ID of the process does not match semperm.[c]uid, and the effective group ID of the process matches semperm.[c]gid, and the appropriate bit of the "group" portion (060) of semperm.mode is set. + effective user ID of the process does not match semperm.[c]uid, and the effective group ID of the process does not match semperm.[c]gid, and the appropriate bit of the "other" portion (06) of semperm.mode is set. Otherwise, the corresponding permissions are denied. Usage notes Using correct argument types It is important to use arguments of the correct type when writing an application using PCILIB. In many cases, the compiler cannot detect argument type mismatches; if an argument of the wrong type is used, the application may fail in an unpredictable way. The best way to be sure the arguments are of the correct type is to make appropriate type declarations or use appropriate type casts. An example is the key argument to the msgget call. The argument to this function is of type keyt, which is defined as a 32-bit value in a UNIX System V operating system. If a DOS program provides an integer constant for this argument, the Microsoft C compiler puts this constant in a 16-bit int value by default. The compiler then generates code that passes this 16-bit value to a procedure that is expecting a 32-bit (keyt) value. The following examples illustrate correct and incorrect use of argument types: return = msgget((key_t)KEY,msgflg); (correct: KEY is 32 bit value) return = msgget(KEY,msgflg); (Incorrect: KEY is 16 bit value) Refer to the manual page for the appropriate function to verify that the arguments used match those expected by the function being called. Using PCILIB polling calls Applications developed using PCILIB will run under both PCILIB and DOS Merge if appropriate programming techniques are used. This section describes how to ensure that applications using message queues, sema- phores, or uwait calls are developed properly. Under a UNIX operating system, when a program makes a call to read a mes- sage queue, the program may specify that the call should wait for a mes- sage to be placed on a message queue before returning. This is referred to as a blocking call. Under DOS, however, blocking message operations are not supported. Thus, applications using PCILIB have to make repeated calls to check for messages until a message becomes available. This checking is referred to as polling. Constant polling may produce a heavy load on the host, resulting in degraded system performance. In order to reduce the load and improve system performance, the application should alternate polling with sleep- ing. PCILIB provides a sleeph function to facilitate this. During the inactivity produced by the sleep time, other processes are able to use the processors in the host or personal computer environment. In choosing the period of time to use for sleep intervals, consider the following general statements: 1. The longer the interval, the lower the load on the host. 2. The shorter the interval, the faster the response time. _________________________________________________________________________ NOTE However, that frequent polling increases the load on the host, possibly slowing response time. An appropriate compromise must be reached. _________________________________________________________________________ These comments apply to semaphore polling and uwait polling as well as message queue polling. Special considerations for DOS Merge In developing a PCILIB application to run under DOS Merge, in addition to the factors listed above, sleep granularity must be considered. Sleep granularity--that is, the time interval between ticks of the system clock--may be different in the DOS Merge environment than in a personal computer. DOS clock interrupts normally occur 18.2 times per second, whereas DOS Merge clock interrupts normally occur once per second. PCILIB sleep calls, when given a value corresponding to n clock-ticks, generally sleep for between n -1 and n clock-tick intervals. For exam- ple, a value corresponding to two clock-ticks results in sleeping between one and two clock-tick intervals. Thus, under DOS Merge (where the default clock-tick interval is one second) the minimum sleep interval ranges between zero to one second. Under DOS, the minimum sleep interval ranges between zero to 1/18.2 seconds. If the fastclk option is enabled under DOS Merge, the clock rate becomes that of a normal personal computer, approximately 18.2 times per second. This provides finer control of the sleep interval, though the latency is still subject to UNIX operating system constraints. Because delivering the extra clock interrupts takes CPU time, running fastclk may improve the response time when the system is not loaded but worsen it when other tasks are competing for CPU usage. fastclk may improve the latency of a DOS task but leads to a higher overall load on the system. An application using the fastclk option should be tested under loaded conditions to see if it improves perfor- mance. Refer to sleeph(PCI) for details on the use of sleeph and fastclk. See also dflthost(PCI), msgctl(PCI), msgget(PCI), msgrcv(PCI), msgsnd(PCI), semctl(PCI), semget(PCI), semop(PCI), sleeph(PCI)