26
26
27
27
static int autocork_debug = -1 ;
28
28
29
+ /* If non-zero says how many app buffers can be autocorked */
30
+ static int autocork_max_qlen ;
31
+
29
32
static unsigned int dump_interval = 300 ; /* 5 minutes */
30
33
31
34
#define NSEC_PER_SEC 1000000000L
@@ -89,6 +92,7 @@ enum uncorkers {
89
92
UNCORKER_recvfrom = 1 << 6 ,
90
93
UNCORKER_recvmsg = 1 << 7 ,
91
94
UNCORKER_select = 1 << 8 ,
95
+ UNCORKER_check_qlen = 1 << 9 ,
92
96
};
93
97
94
98
static const char * uncorkers_str [] = {
@@ -101,6 +105,7 @@ static const char *uncorkers_str[] = {
101
105
"recvfrom" ,
102
106
"recvmsg" ,
103
107
"select" ,
108
+ "check_qlen" ,
104
109
};
105
110
106
111
static void fprintf_uncorkers (FILE * fp , int mask )
@@ -189,7 +194,7 @@ static void libautocork__fprintf_stats(FILE *fp)
189
194
fd_autocork_table [fd ].pktsize_stats .min ,
190
195
fd_autocork_table [fd ].pktsize_stats .max );
191
196
fprintf_uncorkers (fp , fd_autocork_table [fd ].uncorkers );
192
- fputc ( '\n' , fp );
197
+ fprintf ( fp , " %d\n" , autocork_max_qlen );
193
198
}
194
199
}
195
200
fflush (fp );
@@ -217,14 +222,18 @@ static void libautocork__init(void)
217
222
if (s != NULL )
218
223
dump_interval = atoi (s );
219
224
225
+ s = getenv ("AUTOCORK_MAX_QLEN" );
226
+ if (s != NULL )
227
+ autocork_max_qlen = atoi (s );
228
+
220
229
if (dump_interval != 0 ) {
221
230
char filename [PATH_MAX ];
222
231
223
232
snprintf (filename , sizeof (filename ), "%s/libautocork.%d.debug" ,
224
233
getenv ("HOME" ), getpid ());
225
234
dump_fp = fopen (filename , "w" );
226
235
if (dump_fp != NULL )
227
- fputs ("# fd: corklat:samples avg min max qlen:avg min max pktsz:samples avg min max uncorkers\n" , dump_fp );
236
+ fputs ("# fd: corklat:samples avg min max qlen:avg min max pktsz:samples avg min max uncorkers envmaxqlen \n" , dump_fp );
228
237
}
229
238
230
239
atexit (libautocork__exit );
@@ -482,16 +491,27 @@ static void set_pending_frames(int fd, size_t len)
482
491
stats__add_sample (& fd_autocork_table [fd ].pktsize_stats , len );
483
492
}
484
493
494
+ static void check_qlen (int fd )
495
+ {
496
+ if (autocork_max_qlen != 0 &&
497
+ autocork_needed (fd ) &&
498
+ fd_autocork_table [fd ].pending_frames >= autocork_max_qlen )
499
+ push_pending_frames (fd , check_qlen );
500
+ }
501
+
485
502
ssize_t write (int fd , const void * buf , size_t count )
486
503
{
487
504
static ssize_t (* libc_write )(int fd , const void * buf , size_t count );
505
+ ssize_t rc ;
488
506
489
507
hook (write );
490
508
491
509
if (autocork_needed (fd ))
492
510
set_pending_frames (fd , count );
493
511
494
- return libc_write (fd , buf , count );
512
+ rc = libc_write (fd , buf , count );
513
+ check_qlen (fd );
514
+ return rc ;
495
515
}
496
516
497
517
static size_t iov_totlen (const struct iovec * iov , int iovcnt )
@@ -507,49 +527,61 @@ static size_t iov_totlen(const struct iovec *iov, int iovcnt)
507
527
ssize_t writev (int fd , const struct iovec * iov , int iovcnt )
508
528
{
509
529
static ssize_t (* libc_writev )(int fd , const struct iovec * iov , int iovcnt );
530
+ ssize_t rc ;
510
531
511
532
hook (writev );
512
533
513
534
if (autocork_needed (fd ))
514
535
set_pending_frames (fd , iov_totlen (iov , iovcnt ));
515
536
516
- return libc_writev (fd , iov , iovcnt );
537
+ rc = libc_writev (fd , iov , iovcnt );
538
+ check_qlen (fd );
539
+ return rc ;
517
540
}
518
541
519
542
ssize_t send (int s , const void * buf , size_t len , int flags )
520
543
{
521
544
static ssize_t (* libc_send )(int s , const void * buf , size_t len , int flags );
545
+ ssize_t rc ;
522
546
523
547
hook (send );
524
548
525
549
if (autocork_needed (s ))
526
550
set_pending_frames (s , len );
527
551
528
- return libc_send (s , buf , len , flags );
552
+ rc = libc_send (s , buf , len , flags );
553
+ check_qlen (s );
554
+ return rc ;
529
555
}
530
556
531
557
ssize_t sendto (int s , const void * buf , size_t len , int flags ,
532
558
const struct sockaddr * to , socklen_t tolen )
533
559
{
534
560
static ssize_t (* libc_sendto )(int s , const void * buf , size_t len , int flags ,
535
561
const struct sockaddr * to , socklen_t tolen );
562
+ ssize_t rc ;
536
563
537
564
hook (sendto );
538
565
539
566
if (autocork_needed (s ))
540
567
set_pending_frames (s , len );
541
568
542
- return libc_sendto (s , buf , len , flags , to , tolen );
569
+ rc = libc_sendto (s , buf , len , flags , to , tolen );
570
+ check_qlen (s );
571
+ return rc ;
543
572
}
544
573
545
574
ssize_t sendmsg (int s , const struct msghdr * msg , int flags )
546
575
{
547
576
static ssize_t (* libc_sendmsg )(int s , const struct msghdr * msg , int flags );
577
+ ssize_t rc ;
548
578
549
579
hook (sendmsg );
550
580
551
581
if (autocork_needed (s ))
552
582
set_pending_frames (s , iov_totlen (msg -> msg_iov , msg -> msg_iovlen ));
553
583
554
- return libc_sendmsg (s , msg , flags );
584
+ rc = libc_sendmsg (s , msg , flags );
585
+ check_qlen (s );
586
+ return rc ;
555
587
}
0 commit comments