> I have improved the System V semaphore emulation of the QNX4 port.
Please > apply the attached patch to > > backend/port/qnx4 > > Andreas Kardos >
This commit is contained in:
parent
e3fb902991
commit
e02cde4b0a
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.1 1999/12/16 16:52:52 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.2 2000/03/14 18:12:06 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,23 +21,31 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
|
#include "storage/proc.h"
|
||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
|
|
||||||
|
|
||||||
#define SETMAX 32
|
#define SETMAX ((MAXBACKENDS + PROC_NSEMS_PER_SET - 1) / PROC_NSEMS_PER_SET)
|
||||||
#define SEMMAX 16
|
#define SEMMAX (PROC_NSEMS_PER_SET)
|
||||||
|
#define OPMAX 8
|
||||||
|
|
||||||
#define MODE 0777
|
#define MODE 0700
|
||||||
#define SHM_INFO_NAME "SysV_Sem_Info"
|
#define SHM_INFO_NAME "SysV_Sem_Info"
|
||||||
|
|
||||||
|
|
||||||
|
struct pending_ops {
|
||||||
|
int op[OPMAX]; /* array of pending operations */
|
||||||
|
int idx; /* index of first free array member */
|
||||||
|
};
|
||||||
|
|
||||||
struct sem_info {
|
struct sem_info {
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
struct {
|
struct {
|
||||||
key_t key;
|
key_t key;
|
||||||
int nsems;
|
int nsems;
|
||||||
sem_t sem[SEMMAX]; /* array of semaphores */
|
sem_t sem[SEMMAX]; /* array of POSIX semaphores */
|
||||||
pid_t pid[SEMMAX]; /* array of PIDs */
|
struct sem semV[SEMMAX]; /* array of System V semaphore structures */
|
||||||
|
struct pending_ops pendingOps[SEMMAX]; /* array of pending operations */
|
||||||
} set[SETMAX];
|
} set[SETMAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,7 +54,7 @@ static struct sem_info *SemInfo = ( struct sem_info * )-1;
|
|||||||
|
|
||||||
int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
|
int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
|
|
||||||
sem_wait( &SemInfo->sem );
|
sem_wait( &SemInfo->sem );
|
||||||
|
|
||||||
@ -58,30 +66,38 @@ int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch( cmd ) {
|
switch( cmd ) {
|
||||||
|
case GETNCNT:
|
||||||
|
r = SemInfo->set[semid].semV[semnum].semncnt;
|
||||||
|
break;
|
||||||
|
|
||||||
case GETPID:
|
case GETPID:
|
||||||
r = SemInfo->set[semid].pid[semnum];
|
r = SemInfo->set[semid].semV[semnum].sempid;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETVAL:
|
case GETVAL:
|
||||||
r = SemInfo->set[semid].sem[semnum].value;
|
r = SemInfo->set[semid].semV[semnum].semval;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETALL:
|
case GETALL:
|
||||||
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
||||||
arg.array[semnum] = SemInfo->set[semid].sem[semnum].value;
|
arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETVAL:
|
case SETVAL:
|
||||||
SemInfo->set[semid].sem[semnum].value = arg.val;
|
SemInfo->set[semid].semV[semnum].semval = arg.val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETALL:
|
case SETALL:
|
||||||
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
||||||
SemInfo->set[semid].sem[semnum].value = arg.array[semnum];
|
SemInfo->set[semid].semV[semnum].semval = arg.array[semnum];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GETZCNT:
|
||||||
|
r = SemInfo->set[semid].semV[semnum].semzcnt;
|
||||||
|
break;
|
||||||
|
|
||||||
case IPC_RMID:
|
case IPC_RMID:
|
||||||
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
|
||||||
if( sem_destroy( &SemInfo->set[semid].sem[semnum] ) == -1 ) {
|
if( sem_destroy( &SemInfo->set[semid].sem[semnum] ) == -1 ) {
|
||||||
@ -121,12 +137,16 @@ int semget( key_t key, int nsems, int semflg )
|
|||||||
exist = 1;
|
exist = 1;
|
||||||
fd = shm_open( SHM_INFO_NAME, O_RDWR | O_CREAT, MODE );
|
fd = shm_open( SHM_INFO_NAME, O_RDWR | O_CREAT, MODE );
|
||||||
}
|
}
|
||||||
if( fd == -1 ) return fd;
|
if( fd == -1 ) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
/* The size may only be set once. Ignore errors. */
|
/* The size may only be set once. Ignore errors. */
|
||||||
ltrunc( fd, sizeof( struct sem_info ), SEEK_SET );
|
ltrunc( fd, sizeof( struct sem_info ), SEEK_SET );
|
||||||
SemInfo = mmap( NULL, sizeof( struct sem_info ),
|
SemInfo = mmap( NULL, sizeof( struct sem_info ),
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
|
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
|
||||||
if( SemInfo == MAP_FAILED ) return -1;
|
if( SemInfo == MAP_FAILED ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if( !exist ) {
|
if( !exist ) {
|
||||||
/* create semaphore for locking */
|
/* create semaphore for locking */
|
||||||
sem_init( &SemInfo->sem, 1, 1 );
|
sem_init( &SemInfo->sem, 1, 1 );
|
||||||
@ -196,12 +216,12 @@ int semget( key_t key, int nsems, int semflg )
|
|||||||
|
|
||||||
sem_post( &SemInfo->sem );
|
sem_post( &SemInfo->sem );
|
||||||
|
|
||||||
return 0;
|
return semid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int semop( int semid, struct sembuf *sops, size_t nsops )
|
int semop( int semid, struct sembuf *sops, size_t nsops )
|
||||||
{
|
{
|
||||||
int i, j, r = 0, r1, errno1 = 0;
|
int i, r = 0, r1, errno1 = 0, op;
|
||||||
|
|
||||||
sem_wait( &SemInfo->sem );
|
sem_wait( &SemInfo->sem );
|
||||||
|
|
||||||
@ -220,38 +240,67 @@ int semop( int semid, struct sembuf *sops, size_t nsops )
|
|||||||
|
|
||||||
for( i = 0; i < nsops; i++ ) {
|
for( i = 0; i < nsops; i++ ) {
|
||||||
if( sops[i].sem_op < 0 ) {
|
if( sops[i].sem_op < 0 ) {
|
||||||
if( sops[i].sem_flg & IPC_NOWAIT ) {
|
if( SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op ) {
|
||||||
for( j = 0; j < -sops[i].sem_op; j++ ) {
|
if( sops[i].sem_flg & IPC_NOWAIT ) {
|
||||||
if( sem_trywait( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
|
sem_post( &SemInfo->sem );
|
||||||
errno1 = errno;
|
errno = EAGAIN;
|
||||||
r = -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
SemInfo->set[semid].semV[sops[i].sem_num].semncnt++;
|
||||||
|
if( SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX ) {
|
||||||
|
/* pending operations array overflow */
|
||||||
|
sem_post( &SemInfo->sem );
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op;
|
||||||
|
/* suspend */
|
||||||
|
sem_post( &SemInfo->sem ); /* avoid deadlock */
|
||||||
|
r1 = sem_wait( &SemInfo->set[semid].sem[sops[i].sem_num] );
|
||||||
|
sem_wait( &SemInfo->sem );
|
||||||
|
if( r1 ) {
|
||||||
|
errno1 = errno;
|
||||||
|
r = r1;
|
||||||
|
/* remove pending operation */
|
||||||
|
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
|
||||||
|
}
|
||||||
|
SemInfo->set[semid].semV[sops[i].sem_num].semncnt--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( j = 0; j < -sops[i].sem_op; j++ ) {
|
SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
|
||||||
sem_post( &SemInfo->sem ); /* avoid deadlock */
|
|
||||||
r1 = sem_wait( &SemInfo->set[semid].sem[sops[i].sem_num] );
|
|
||||||
sem_wait( &SemInfo->sem );
|
|
||||||
if( r1 ) {
|
|
||||||
errno1 = errno;
|
|
||||||
r = r1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( sops[i].sem_op > 0 ) {
|
else if( sops[i].sem_op > 0 ) {
|
||||||
for( j = 0; j < sops[i].sem_op; j++ ) {
|
SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op;
|
||||||
if( sem_post( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
|
op = sops[i].sem_op;
|
||||||
errno1 = errno;
|
while( op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0 ) { /* operations pending */
|
||||||
r = -1;
|
if( SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] + op >= 0 ) {
|
||||||
|
/* unsuspend processes */
|
||||||
|
if( sem_post( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
|
||||||
|
errno1 = errno;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
/* adjust pending operations */
|
||||||
|
op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx];
|
||||||
|
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* adjust pending operations */
|
||||||
|
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] += op;
|
||||||
|
op = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* sops[i].sem_op == 0 */ {
|
else /* sops[i].sem_op == 0 */ {
|
||||||
/* not supported */
|
/* not supported */
|
||||||
|
sem_post( &SemInfo->sem );
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
SemInfo->set[semid].pid[sops[i].sem_num] = getpid( );
|
SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid( );
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_post( &SemInfo->sem );
|
sem_post( &SemInfo->sem );
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.h,v 1.1 1999/12/16 16:52:52 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.h,v 1.2 2000/03/14 18:12:06 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,37 +17,48 @@
|
|||||||
|
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Semctl Command Definitions.
|
* Semctl Command Definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GETNCNT 3 /* get semncnt */
|
#define GETNCNT 3 /* get semncnt */
|
||||||
#define GETPID 4 /* get sempid */
|
#define GETPID 4 /* get sempid */
|
||||||
#define GETVAL 5 /* get semval */
|
#define GETVAL 5 /* get semval */
|
||||||
#define GETALL 6 /* get all semval's */
|
#define GETALL 6 /* get all semval's */
|
||||||
#define GETZCNT 7 /* get semzcnt */
|
#define GETZCNT 7 /* get semzcnt */
|
||||||
#define SETVAL 8 /* set semval */
|
#define SETVAL 8 /* set semval */
|
||||||
#define SETALL 9 /* set all semval's */
|
#define SETALL 9 /* set all semval's */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User semaphore template for semop system calls.
|
* There is one semaphore structure for each semaphore in the system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct sem {
|
||||||
|
ushort_t semval; /* semaphore text map address */
|
||||||
|
pid_t sempid; /* pid of last operation */
|
||||||
|
ushort_t semncnt; /* # awaiting semval > cval */
|
||||||
|
ushort_t semzcnt; /* # awaiting semval = 0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User semaphore template for semop system calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct sembuf {
|
struct sembuf {
|
||||||
ushort_t sem_num; /* semaphore # */
|
ushort_t sem_num; /* semaphore # */
|
||||||
short sem_op; /* semaphore operation */
|
short sem_op; /* semaphore operation */
|
||||||
short sem_flg; /* operation flags */
|
short sem_flg; /* operation flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int semctl( int semid, int semnum, int cmd, /*...*/union semun arg );
|
extern int semctl( int semid, int semnum, int cmd, /*...*/union semun arg );
|
||||||
extern int semget( key_t key, int nsems, int semflg );
|
extern int semget( key_t key, int nsems, int semflg );
|
||||||
extern int semop( int semid, struct sembuf *sops, size_t nsops );
|
extern int semop( int semid, struct sembuf *sops, size_t nsops );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7,12 +7,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/tstsem.c,v 1.1 1999/12/16 16:52:52 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/tstsem.c,v 1.2 2000/03/14 18:12:06 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -22,9 +23,18 @@
|
|||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
|
|
||||||
|
|
||||||
#define SEMMAX 1
|
#define SEMMAX 16
|
||||||
#define OPSMAX 1
|
#define OPSMAX 1
|
||||||
|
|
||||||
|
static int semid;
|
||||||
|
|
||||||
|
static void sig_handler( int sig_no )
|
||||||
|
{
|
||||||
|
union semun arg;
|
||||||
|
int i = semctl( semid, 0, GETNCNT, arg );
|
||||||
|
if( i == -1 ) perror( "semctl" );
|
||||||
|
else printf( "semval = %d\n", i );
|
||||||
|
}
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
@ -34,7 +44,7 @@ int main( int argc, char **argv )
|
|||||||
int nsems = SEMMAX;
|
int nsems = SEMMAX;
|
||||||
int semflg = 0;
|
int semflg = 0;
|
||||||
int unlink = 0;
|
int unlink = 0;
|
||||||
int semid, i;
|
int i;
|
||||||
struct sembuf sops[OPSMAX];
|
struct sembuf sops[OPSMAX];
|
||||||
u_short array[SEMMAX];
|
u_short array[SEMMAX];
|
||||||
union semun arg;
|
union semun arg;
|
||||||
@ -67,8 +77,11 @@ int main( int argc, char **argv )
|
|||||||
exit( semid );
|
exit( semid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* test signal interrupts */
|
||||||
|
signal( SIGTERM, sig_handler );
|
||||||
|
|
||||||
do {
|
do {
|
||||||
printf( "(-)sem_op, (+)sem_op, (G)ETVAL, (S)ETVAL, GET(P)ID, GET(A)LL, SETA(L)L, e(x)it: " );
|
printf( "(-)sem_op, (+)sem_op, (G)ETVAL, (S)ETVAL, GET(P)ID, GET(A)LL, SETA(L)L, GET(N)CNT, GET(Z)CNT, e(x)it: " );
|
||||||
scanf( "%s", s );
|
scanf( "%s", s );
|
||||||
switch( s[0] ) {
|
switch( s[0] ) {
|
||||||
case '-':
|
case '-':
|
||||||
@ -122,6 +135,20 @@ int main( int argc, char **argv )
|
|||||||
}
|
}
|
||||||
if( semctl( semid, 0, SETALL, arg ) == -1 )perror( "semctl" );
|
if( semctl( semid, 0, SETALL, arg ) == -1 )perror( "semctl" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
case 'n':
|
||||||
|
i = semctl( semid, 0, GETNCNT, arg );
|
||||||
|
if( i == -1 ) perror( "semctl" );
|
||||||
|
else printf( "semval = %d\n", i );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Z':
|
||||||
|
case 'z':
|
||||||
|
i = semctl( semid, 0, GETZCNT, arg );
|
||||||
|
if( i == -1 ) perror( "semctl" );
|
||||||
|
else printf( "semval = %d\n", i );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while( s[0] != 'x' );
|
while( s[0] != 'x' );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user