cygserver - Postgres Multiple connection Load Testing - Inifinte Loop
Marco Atzeri
marco.atzeri@gmail.com
Sat Mar 25 10:55:00 GMT 2017
On 24/03/2017 18:11, Corinna Vinschen wrote:
> Hi Noah,
>
>>
>> On GNU/Linux, AIX, and Solaris, the processes keep busy and finish one million
>> lock/unlock cycles apiece in a few minutes. On Cygwin, they hang within a few
>> seconds and under one hundred cycles apiece. At that point, cygserver is
>> unresponsive to other clients; for example, "strace /bin/true", opening a new
>> Cygwin terminal, "cat /proc/sysvipc/sem" and "cygserver -S" all hang. In most
>> tests, cygserver was not consuming CPU while unresponsive.
>
>
> I pushed a patchset now, and uploaded new developer snapshots for
> testing to https://cygwin.com/snapshots/
>
> I'm also going to create a 2.8.0-0.4 test release later today.
>
> Please give it a try, and please note that *all* patches affect
> cygserver itself, so you have to test the new cygserver in the
> first place. The Cygwin DLL is not affected by the changes.
>
>
> Thanks,
> Corinna
>
Hi Corinna,
just noted a small glitch.
Attached a modification of Noah's test, it now accepts the number of
workers and semaphore are as before workers/4
./sema_parallel-2 32
worker ....
OK
./sema_parallel-2 64
semget
semget: Invalid argument
If I restart the cygserver
./sema_parallel-2 64
worker ....
OK
./sema_parallel-2 128
semget
semget: Invalid argument
It seems that the number of max available semaphores is frozen to first
call value.
-------------- next part --------------
/*
* Demonstrate cygserver hang under concurrent sysv semaphore traffic. Run
* without arguments. Output will cease within a few seconds, and cygserver
* will be unresponsive to all clients.
*
* This is compatible with default cygserver settings; it uses a single
* semaphore set of four semaphores.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define SEM_KEY 0x631a2c3e
#define N_CYCLE 1000000
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
static int print_every = 1;
/* In parallel, N_WORKER processes run this function. */
static int do_worker(int ordinal, int set, int N_SEMA)
{
int i;
struct sembuf op;
printf("start worker %d\n", ordinal);
fflush(stdout);
op.sem_flg = 0;
for (i = 1; i <= N_CYCLE; i++)
{
op.sem_num = random() % N_SEMA;
op.sem_op = -1;
if (0 > semop(set, &op, 1))
{
perror("semop");
return 1;
}
op.sem_op = 1;
if (0 > semop(set, &op, 1))
{
perror("semop");
return 1;
}
if (i % print_every == 0)
{
printf("worker %d: %d cycles elapsed\n", ordinal, i);
fflush(stdout);
}
}
return 0;
}
int main(int argc, char **argv)
{
int status = 1, set, i, child_status;
int N_WORKER, N_SEMA;
switch(argc){
case 3:
print_every = atoi(argv[2]);
case 2:
N_WORKER=atoi(argv[1]);
N_SEMA= (N_WORKER/4);
break;
default:
fprintf(stderr, "Usage: sema_parallel workers [print-every-N]\n");
return status;
}
puts("semget");
fflush(stdout);
set = semget(SEM_KEY, N_SEMA, IPC_CREAT | 0600);
if (set == -1)
{
perror("semget");
return status;
}
puts("SETVAL");
fflush(stdout);
for (i = 0; i < N_SEMA; i++)
{
union semun s;
s.val = 1;
if (0 > semctl(set, i, SETVAL, s))
{
perror("semctl(SETVAL)");
goto cleanup;
}
}
for (i = 0; i < N_WORKER; i++)
{
pid_t pid;
pid = fork();
switch (pid)
{
case -1:
perror("fork");
goto cleanup;
case 0:
return do_worker(i, set, N_SEMA );
}
}
status = 0;
cleanup:
while (wait(&child_status) != -1)
;
if (errno != ECHILD)
{
perror("wait");
status = 1;
}
if (0 > semctl(set, 0, IPC_RMID))
{
perror("semtctl(IPC_RMID)");
status = 1;
}
return status;
}
-------------- next part --------------
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
More information about the Cygwin
mailing list