1
1
/*
2
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.66 2007/05/24 18:54:10 tgl Exp $
2
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.67 2007/07/06 13:36:55 wieck Exp $
3
3
*
4
4
* pgbench: a simple benchmark program for PostgreSQL
5
5
* written by Tatsuo Ishii
@@ -114,6 +114,8 @@ typedef struct
114
114
int ecnt ; /* error count */
115
115
int listen ; /* 0 indicates that an async query has been
116
116
* sent */
117
+ int sleeping ; /* 1 indicates that the client is napping */
118
+ struct timeval until ; /* napping until */
117
119
Variable * variables ; /* array of variable definitions */
118
120
int nvariables ;
119
121
struct timeval txn_begin ; /* used for measuring latencies */
@@ -445,6 +447,20 @@ doCustom(CState * state, int n, int debug)
445
447
top :
446
448
commands = sql_files [st -> use_file ];
447
449
450
+ if (st -> sleeping )
451
+ { /* are we sleeping? */
452
+ int usec ;
453
+ struct timeval now ;
454
+
455
+ gettimeofday (& now , NULL );
456
+ usec = (st -> until .tv_sec - now .tv_sec ) * 1000000 +
457
+ st -> until .tv_usec - now .tv_usec ;
458
+ if (usec <= 0 )
459
+ st -> sleeping = 0 ; /* Done sleeping, go ahead with next command */
460
+ else
461
+ return ; /* Still sleeping, nothing to do here */
462
+ }
463
+
448
464
if (st -> listen )
449
465
{ /* are we receiver? */
450
466
if (commands [st -> state ]-> type == SQL_COMMAND )
@@ -711,6 +727,32 @@ doCustom(CState * state, int n, int debug)
711
727
712
728
st -> listen = 1 ;
713
729
}
730
+ else if (pg_strcasecmp (argv [0 ], "usleep" ) == 0 )
731
+ {
732
+ char * var ;
733
+ int usec ;
734
+ struct timeval now ;
735
+
736
+ if (* argv [1 ] == ':' )
737
+ {
738
+ if ((var = getVariable (st , argv [1 ] + 1 )) == NULL )
739
+ {
740
+ fprintf (stderr , "%s: undefined variable %s\n" , argv [0 ], argv [1 ]);
741
+ st -> ecnt ++ ;
742
+ return ;
743
+ }
744
+ usec = atoi (var );
745
+ }
746
+ else
747
+ usec = atoi (argv [1 ]);
748
+
749
+ gettimeofday (& now , NULL );
750
+ st -> until .tv_sec = now .tv_sec + (now .tv_usec + usec ) / 1000000 ;
751
+ st -> until .tv_usec = (now .tv_usec + usec ) % 1000000 ;
752
+ st -> sleeping = 1 ;
753
+
754
+ st -> listen = 1 ;
755
+ }
714
756
715
757
goto top ;
716
758
}
@@ -921,9 +963,21 @@ process_commands(char *buf)
921
963
fprintf (stderr , "%s: extra argument \"%s\" ignored\n" ,
922
964
my_commands -> argv [0 ], my_commands -> argv [j ]);
923
965
}
966
+ else if (pg_strcasecmp (my_commands -> argv [0 ], "usleep" ) == 0 )
967
+ {
968
+ if (my_commands -> argc < 2 )
969
+ {
970
+ fprintf (stderr , "%s: missing argument\n" , my_commands -> argv [0 ]);
971
+ return NULL ;
972
+ }
973
+
974
+ for (j = 2 ; j < my_commands -> argc ; j ++ )
975
+ fprintf (stderr , "%s: extra argument \"%s\" ignored\n" ,
976
+ my_commands -> argv [0 ], my_commands -> argv [j ]);
977
+ }
924
978
else
925
979
{
926
- fprintf (stderr , "invalid command %s\n" , my_commands -> argv [0 ]);
980
+ fprintf (stderr , "Invalid command %s\n" , my_commands -> argv [0 ]);
927
981
return NULL ;
928
982
}
929
983
}
@@ -1143,6 +1197,9 @@ main(int argc, char **argv)
1143
1197
fd_set input_mask ;
1144
1198
int nsocks ; /* return from select(2) */
1145
1199
int maxsock ; /* max socket number to be waited */
1200
+ struct timeval now ;
1201
+ struct timeval timeout ;
1202
+ int min_usec ;
1146
1203
1147
1204
#ifdef HAVE_GETRLIMIT
1148
1205
struct rlimit rlim ;
@@ -1526,11 +1583,33 @@ main(int argc, char **argv)
1526
1583
FD_ZERO (& input_mask );
1527
1584
1528
1585
maxsock = -1 ;
1586
+ min_usec = -1 ;
1529
1587
for (i = 0 ; i < nclients ; i ++ )
1530
1588
{
1531
1589
Command * * commands = sql_files [state [i ].use_file ];
1532
1590
1533
- if (state [i ].con && commands [state [i ].state ]-> type != META_COMMAND )
1591
+ if (state [i ].sleeping )
1592
+ {
1593
+ int this_usec ;
1594
+ int sock = PQsocket (state [i ].con );
1595
+
1596
+ if (min_usec < 0 )
1597
+ {
1598
+ gettimeofday (& now , NULL );
1599
+ min_usec = 0 ;
1600
+ }
1601
+
1602
+ this_usec = (state [i ].until .tv_sec - now .tv_sec ) * 1000000 +
1603
+ state [i ].until .tv_usec - now .tv_usec ;
1604
+
1605
+ if (this_usec > 0 && (min_usec == 0 || this_usec < min_usec ))
1606
+ min_usec = this_usec ;
1607
+
1608
+ FD_SET (sock , & input_mask );
1609
+ if (maxsock < sock )
1610
+ maxsock = sock ;
1611
+ }
1612
+ else if (state [i ].con && commands [state [i ].state ]-> type != META_COMMAND )
1534
1613
{
1535
1614
int sock = PQsocket (state [i ].con );
1536
1615
@@ -1547,8 +1626,18 @@ main(int argc, char **argv)
1547
1626
1548
1627
if (maxsock != -1 )
1549
1628
{
1550
- if ((nsocks = select (maxsock + 1 , & input_mask , (fd_set * ) NULL ,
1551
- (fd_set * ) NULL , (struct timeval * ) NULL )) < 0 )
1629
+ if (min_usec >= 0 )
1630
+ {
1631
+ timeout .tv_sec = min_usec / 1000000 ;
1632
+ timeout .tv_usec = min_usec % 1000000 ;
1633
+
1634
+ nsocks = select (maxsock + 1 , & input_mask , (fd_set * ) NULL ,
1635
+ (fd_set * ) NULL , & timeout );
1636
+ }
1637
+ else
1638
+ nsocks = select (maxsock + 1 , & input_mask , (fd_set * ) NULL ,
1639
+ (fd_set * ) NULL , (struct timeval * ) NULL );
1640
+ if (nsocks < 0 )
1552
1641
{
1553
1642
if (errno == EINTR )
1554
1643
continue ;
@@ -1557,6 +1646,7 @@ main(int argc, char **argv)
1557
1646
fprintf (stderr , "select failed: %s\n" , strerror (errno ));
1558
1647
exit (1 );
1559
1648
}
1649
+ #ifdef NOT_USED
1560
1650
else if (nsocks == 0 )
1561
1651
{ /* timeout */
1562
1652
fprintf (stderr , "select timeout\n" );
@@ -1567,6 +1657,7 @@ main(int argc, char **argv)
1567
1657
}
1568
1658
exit (0 );
1569
1659
}
1660
+ #endif
1570
1661
}
1571
1662
1572
1663
/* ok, backend returns reply */
0 commit comments