Skip to content

Commit e02cde4

Browse files
committed
> I have improved the System V semaphore emulation of the QNX4 port.
Please > apply the attached patch to > > backend/port/qnx4 > > Andreas Kardos >
1 parent e3fb902 commit e02cde4

File tree

3 files changed

+145
-58
lines changed

3 files changed

+145
-58
lines changed

src/backend/port/qnx4/sem.c

Lines changed: 87 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.1 1999/12/16 16:52:52 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.2 2000/03/14 18:12:06 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,23 +21,31 @@
2121
#include <sys/mman.h>
2222
#include "postgres.h"
2323
#include "storage/ipc.h"
24+
#include "storage/proc.h"
2425
#include <sys/sem.h>
2526

2627

27-
#define SETMAX 32
28-
#define SEMMAX 16
28+
#define SETMAX ((MAXBACKENDS + PROC_NSEMS_PER_SET - 1) / PROC_NSEMS_PER_SET)
29+
#define SEMMAX (PROC_NSEMS_PER_SET)
30+
#define OPMAX 8
2931

30-
#define MODE 0777
32+
#define MODE 0700
3133
#define SHM_INFO_NAME "SysV_Sem_Info"
3234

3335

36+
struct pending_ops {
37+
int op[OPMAX]; /* array of pending operations */
38+
int idx; /* index of first free array member */
39+
};
40+
3441
struct sem_info {
3542
sem_t sem;
3643
struct {
37-
key_t key;
38-
int nsems;
39-
sem_t sem[SEMMAX]; /* array of semaphores */
40-
pid_t pid[SEMMAX]; /* array of PIDs */
44+
key_t key;
45+
int nsems;
46+
sem_t sem[SEMMAX]; /* array of POSIX semaphores */
47+
struct sem semV[SEMMAX]; /* array of System V semaphore structures */
48+
struct pending_ops pendingOps[SEMMAX]; /* array of pending operations */
4149
} set[SETMAX];
4250
};
4351

@@ -46,7 +54,7 @@ static struct sem_info *SemInfo = ( struct sem_info * )-1;
4654

4755
int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
4856
{
49-
int r;
57+
int r = 0;
5058

5159
sem_wait( &SemInfo->sem );
5260

@@ -58,30 +66,38 @@ int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
5866
}
5967

6068
switch( cmd ) {
69+
case GETNCNT:
70+
r = SemInfo->set[semid].semV[semnum].semncnt;
71+
break;
72+
6173
case GETPID:
62-
r = SemInfo->set[semid].pid[semnum];
74+
r = SemInfo->set[semid].semV[semnum].sempid;
6375
break;
6476

6577
case GETVAL:
66-
r = SemInfo->set[semid].sem[semnum].value;
78+
r = SemInfo->set[semid].semV[semnum].semval;
6779
break;
6880

6981
case GETALL:
7082
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
71-
arg.array[semnum] = SemInfo->set[semid].sem[semnum].value;
83+
arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval;
7284
}
7385
break;
7486

7587
case SETVAL:
76-
SemInfo->set[semid].sem[semnum].value = arg.val;
88+
SemInfo->set[semid].semV[semnum].semval = arg.val;
7789
break;
7890

7991
case SETALL:
8092
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
81-
SemInfo->set[semid].sem[semnum].value = arg.array[semnum];
93+
SemInfo->set[semid].semV[semnum].semval = arg.array[semnum];
8294
}
8395
break;
8496

97+
case GETZCNT:
98+
r = SemInfo->set[semid].semV[semnum].semzcnt;
99+
break;
100+
85101
case IPC_RMID:
86102
for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
87103
if( sem_destroy( &SemInfo->set[semid].sem[semnum] ) == -1 ) {
@@ -121,12 +137,16 @@ int semget( key_t key, int nsems, int semflg )
121137
exist = 1;
122138
fd = shm_open( SHM_INFO_NAME, O_RDWR | O_CREAT, MODE );
123139
}
124-
if( fd == -1 ) return fd;
140+
if( fd == -1 ) {
141+
return fd;
142+
}
125143
/* The size may only be set once. Ignore errors. */
126144
ltrunc( fd, sizeof( struct sem_info ), SEEK_SET );
127145
SemInfo = mmap( NULL, sizeof( struct sem_info ),
128146
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
129-
if( SemInfo == MAP_FAILED ) return -1;
147+
if( SemInfo == MAP_FAILED ) {
148+
return -1;
149+
}
130150
if( !exist ) {
131151
/* create semaphore for locking */
132152
sem_init( &SemInfo->sem, 1, 1 );
@@ -196,12 +216,12 @@ int semget( key_t key, int nsems, int semflg )
196216

197217
sem_post( &SemInfo->sem );
198218

199-
return 0;
219+
return semid;
200220
}
201221

202222
int semop( int semid, struct sembuf *sops, size_t nsops )
203223
{
204-
int i, j, r = 0, r1, errno1 = 0;
224+
int i, r = 0, r1, errno1 = 0, op;
205225

206226
sem_wait( &SemInfo->sem );
207227

@@ -220,38 +240,67 @@ int semop( int semid, struct sembuf *sops, size_t nsops )
220240

221241
for( i = 0; i < nsops; i++ ) {
222242
if( sops[i].sem_op < 0 ) {
223-
if( sops[i].sem_flg & IPC_NOWAIT ) {
224-
for( j = 0; j < -sops[i].sem_op; j++ ) {
225-
if( sem_trywait( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
226-
errno1 = errno;
227-
r = -1;
228-
}
243+
if( SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op ) {
244+
if( sops[i].sem_flg & IPC_NOWAIT ) {
245+
sem_post( &SemInfo->sem );
246+
errno = EAGAIN;
247+
return -1;
229248
}
249+
SemInfo->set[semid].semV[sops[i].sem_num].semncnt++;
250+
if( SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX ) {
251+
/* pending operations array overflow */
252+
sem_post( &SemInfo->sem );
253+
errno = ERANGE;
254+
return -1;
255+
}
256+
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op;
257+
/* suspend */
258+
sem_post( &SemInfo->sem ); /* avoid deadlock */
259+
r1 = sem_wait( &SemInfo->set[semid].sem[sops[i].sem_num] );
260+
sem_wait( &SemInfo->sem );
261+
if( r1 ) {
262+
errno1 = errno;
263+
r = r1;
264+
/* remove pending operation */
265+
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
266+
}
267+
else {
268+
SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
269+
}
270+
SemInfo->set[semid].semV[sops[i].sem_num].semncnt--;
230271
}
231272
else {
232-
for( j = 0; j < -sops[i].sem_op; j++ ) {
233-
sem_post( &SemInfo->sem ); /* avoid deadlock */
234-
r1 = sem_wait( &SemInfo->set[semid].sem[sops[i].sem_num] );
235-
sem_wait( &SemInfo->sem );
236-
if( r1 ) {
237-
errno1 = errno;
238-
r = r1;
239-
}
240-
}
273+
SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
241274
}
242275
}
243276
else if( sops[i].sem_op > 0 ) {
244-
for( j = 0; j < sops[i].sem_op; j++ ) {
245-
if( sem_post( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
246-
errno1 = errno;
247-
r = -1;
277+
SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op;
278+
op = sops[i].sem_op;
279+
while( op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0 ) { /* operations pending */
280+
if( SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] + op >= 0 ) {
281+
/* unsuspend processes */
282+
if( sem_post( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
283+
errno1 = errno;
284+
r = -1;
285+
}
286+
/* adjust pending operations */
287+
op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx];
288+
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
289+
}
290+
else {
291+
/* adjust pending operations */
292+
SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] += op;
293+
op = 0;
248294
}
249295
}
250296
}
251297
else /* sops[i].sem_op == 0 */ {
252298
/* not supported */
299+
sem_post( &SemInfo->sem );
300+
errno = ENOSYS;
301+
return -1;
253302
}
254-
SemInfo->set[semid].pid[sops[i].sem_num] = getpid( );
303+
SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid( );
255304
}
256305

257306
sem_post( &SemInfo->sem );

src/backend/port/qnx4/sem.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.h,v 1.1 1999/12/16 16:52:52 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.h,v 1.2 2000/03/14 18:12:06 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,37 +17,48 @@
1717

1818
#include <sys/ipc.h>
1919

20-
#ifdef __cplusplus
20+
#ifdef __cplusplus
2121
extern "C" {
2222
#endif
2323

2424
/*
25-
* Semctl Command Definitions.
25+
* Semctl Command Definitions.
2626
*/
2727

28-
#define GETNCNT 3 /* get semncnt */
29-
#define GETPID 4 /* get sempid */
30-
#define GETVAL 5 /* get semval */
31-
#define GETALL 6 /* get all semval's */
32-
#define GETZCNT 7 /* get semzcnt */
33-
#define SETVAL 8 /* set semval */
34-
#define SETALL 9 /* set all semval's */
28+
#define GETNCNT 3 /* get semncnt */
29+
#define GETPID 4 /* get sempid */
30+
#define GETVAL 5 /* get semval */
31+
#define GETALL 6 /* get all semval's */
32+
#define GETZCNT 7 /* get semzcnt */
33+
#define SETVAL 8 /* set semval */
34+
#define SETALL 9 /* set all semval's */
3535

3636
/*
37-
* User semaphore template for semop system calls.
37+
* There is one semaphore structure for each semaphore in the system.
38+
*/
39+
40+
struct sem {
41+
ushort_t semval; /* semaphore text map address */
42+
pid_t sempid; /* pid of last operation */
43+
ushort_t semncnt; /* # awaiting semval > cval */
44+
ushort_t semzcnt; /* # awaiting semval = 0 */
45+
};
46+
47+
/*
48+
* User semaphore template for semop system calls.
3849
*/
3950

4051
struct sembuf {
41-
ushort_t sem_num; /* semaphore # */
42-
short sem_op; /* semaphore operation */
43-
short sem_flg; /* operation flags */
52+
ushort_t sem_num; /* semaphore # */
53+
short sem_op; /* semaphore operation */
54+
short sem_flg; /* operation flags */
4455
};
4556

4657
extern int semctl( int semid, int semnum, int cmd, /*...*/union semun arg );
4758
extern int semget( key_t key, int nsems, int semflg );
4859
extern int semop( int semid, struct sembuf *sops, size_t nsops );
4960

50-
#ifdef __cplusplus
61+
#ifdef __cplusplus
5162
}
5263
#endif
5364

src/backend/port/qnx4/tstsem.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/tstsem.c,v 1.1 1999/12/16 16:52:52 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/tstsem.c,v 1.2 2000/03/14 18:12:06 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
1414

1515

16+
#include <signal.h>
1617
#include <stdio.h>
1718
#include <stdlib.h>
1819
#include <unistd.h>
@@ -22,9 +23,18 @@
2223
#include <sys/sem.h>
2324

2425

25-
#define SEMMAX 1
26-
#define OPSMAX 1
26+
#define SEMMAX 16
27+
#define OPSMAX 1
2728

29+
static int semid;
30+
31+
static void sig_handler( int sig_no )
32+
{
33+
union semun arg;
34+
int i = semctl( semid, 0, GETNCNT, arg );
35+
if( i == -1 ) perror( "semctl" );
36+
else printf( "semval = %d\n", i );
37+
}
2838

2939
int main( int argc, char **argv )
3040
{
@@ -34,7 +44,7 @@ int main( int argc, char **argv )
3444
int nsems = SEMMAX;
3545
int semflg = 0;
3646
int unlink = 0;
37-
int semid, i;
47+
int i;
3848
struct sembuf sops[OPSMAX];
3949
u_short array[SEMMAX];
4050
union semun arg;
@@ -67,8 +77,11 @@ int main( int argc, char **argv )
6777
exit( semid );
6878
}
6979

80+
/* test signal interrupts */
81+
signal( SIGTERM, sig_handler );
82+
7083
do {
71-
printf( "(-)sem_op, (+)sem_op, (G)ETVAL, (S)ETVAL, GET(P)ID, GET(A)LL, SETA(L)L, e(x)it: " );
84+
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: " );
7285
scanf( "%s", s );
7386
switch( s[0] ) {
7487
case '-':
@@ -122,6 +135,20 @@ int main( int argc, char **argv )
122135
}
123136
if( semctl( semid, 0, SETALL, arg ) == -1 )perror( "semctl" );
124137
break;
138+
139+
case 'N':
140+
case 'n':
141+
i = semctl( semid, 0, GETNCNT, arg );
142+
if( i == -1 ) perror( "semctl" );
143+
else printf( "semval = %d\n", i );
144+
break;
145+
146+
case 'Z':
147+
case 'z':
148+
i = semctl( semid, 0, GETZCNT, arg );
149+
if( i == -1 ) perror( "semctl" );
150+
else printf( "semval = %d\n", i );
151+
break;
125152
}
126153
}
127154
while( s[0] != 'x' );

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy