@@ -362,7 +362,7 @@ static const char *output_fields;
362
362
363
363
#define DEF_KEY_LOCK (name , header , fn_suffix , len ) \
364
364
{ #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} }
365
- struct lock_key keys [] = {
365
+ static struct lock_key report_keys [] = {
366
366
DEF_KEY_LOCK (acquired , "acquired" , nr_acquired , 10 ),
367
367
DEF_KEY_LOCK (contended , "contended" , nr_contended , 10 ),
368
368
DEF_KEY_LOCK (avg_wait , "avg wait" , avg_wait_time , 12 ),
@@ -374,9 +374,24 @@ struct lock_key keys[] = {
374
374
{ }
375
375
};
376
376
377
- static int select_key (void )
377
+ static struct lock_key contention_keys [] = {
378
+ DEF_KEY_LOCK (contended , "contended" , nr_contended , 10 ),
379
+ DEF_KEY_LOCK (wait_total , "total wait" , wait_time_total , 12 ),
380
+ DEF_KEY_LOCK (wait_max , "max wait" , wait_time_max , 12 ),
381
+ DEF_KEY_LOCK (wait_min , "min wait" , wait_time_min , 12 ),
382
+ DEF_KEY_LOCK (avg_wait , "avg wait" , avg_wait_time , 12 ),
383
+
384
+ /* extra comparisons much complicated should be here */
385
+ { }
386
+ };
387
+
388
+ static int select_key (bool contention )
378
389
{
379
390
int i ;
391
+ struct lock_key * keys = report_keys ;
392
+
393
+ if (contention )
394
+ keys = contention_keys ;
380
395
381
396
for (i = 0 ; keys [i ].name ; i ++ ) {
382
397
if (!strcmp (keys [i ].name , sort_key )) {
@@ -394,17 +409,21 @@ static int select_key(void)
394
409
return -1 ;
395
410
}
396
411
397
- static int add_output_field (struct list_head * head , char * name )
412
+ static int add_output_field (bool contention , char * name )
398
413
{
399
414
int i ;
415
+ struct lock_key * keys = report_keys ;
416
+
417
+ if (contention )
418
+ keys = contention_keys ;
400
419
401
420
for (i = 0 ; keys [i ].name ; i ++ ) {
402
421
if (strcmp (keys [i ].name , name ))
403
422
continue ;
404
423
405
424
/* prevent double link */
406
425
if (list_empty (& keys [i ].list ))
407
- list_add_tail (& keys [i ].list , head );
426
+ list_add_tail (& keys [i ].list , & lock_keys );
408
427
409
428
return 0 ;
410
429
}
@@ -413,10 +432,14 @@ static int add_output_field(struct list_head *head, char *name)
413
432
return -1 ;
414
433
}
415
434
416
- static int setup_output_field (const char * str )
435
+ static int setup_output_field (bool contention , const char * str )
417
436
{
418
437
char * tok , * tmp , * orig ;
419
438
int i , ret = 0 ;
439
+ struct lock_key * keys = report_keys ;
440
+
441
+ if (contention )
442
+ keys = contention_keys ;
420
443
421
444
/* no output field given: use all of them */
422
445
if (str == NULL ) {
@@ -433,7 +456,7 @@ static int setup_output_field(const char *str)
433
456
return - ENOMEM ;
434
457
435
458
while ((tok = strsep (& tmp , "," )) != NULL ){
436
- ret = add_output_field (& lock_keys , tok );
459
+ ret = add_output_field (contention , tok );
437
460
if (ret < 0 )
438
461
break ;
439
462
}
@@ -1609,10 +1632,10 @@ static int __cmd_report(bool display_info)
1609
1632
goto out_delete ;
1610
1633
}
1611
1634
1612
- if (setup_output_field (output_fields ))
1635
+ if (setup_output_field (false, output_fields ))
1613
1636
goto out_delete ;
1614
1637
1615
- if (select_key ())
1638
+ if (select_key (false ))
1616
1639
goto out_delete ;
1617
1640
1618
1641
if (show_thread_stats )
@@ -1674,11 +1697,10 @@ static int __cmd_contention(void)
1674
1697
goto out_delete ;
1675
1698
}
1676
1699
1677
- if (setup_output_field ("contended,wait_total,wait_max,avg_wait" ))
1700
+ if (setup_output_field (true, output_fields ))
1678
1701
goto out_delete ;
1679
1702
1680
- sort_key = "wait_total" ;
1681
- if (select_key ())
1703
+ if (select_key (true))
1682
1704
goto out_delete ;
1683
1705
1684
1706
aggr_mode = LOCK_AGGR_CALLER ;
@@ -1817,6 +1839,10 @@ int cmd_lock(int argc, const char **argv)
1817
1839
};
1818
1840
1819
1841
const struct option contention_options [] = {
1842
+ OPT_STRING ('k' , "key" , & sort_key , "wait_total" ,
1843
+ "key for sorting (contended / wait_total / wait_max / wait_min / avg_wait)" ),
1844
+ OPT_STRING ('F' , "field" , & output_fields , "contended,wait_total,wait_max,avg_wait" ,
1845
+ "output fields (contended / wait_total / wait_max / wait_min / avg_wait)" ),
1820
1846
OPT_PARENT (lock_options )
1821
1847
};
1822
1848
@@ -1876,6 +1902,9 @@ int cmd_lock(int argc, const char **argv)
1876
1902
rc = __cmd_report (true);
1877
1903
} else if (strlen (argv [0 ]) > 2 && strstarts ("contention" , argv [0 ])) {
1878
1904
trace_handler = & contention_lock_ops ;
1905
+ sort_key = "wait_total" ;
1906
+ output_fields = "contended,wait_total,wait_max,avg_wait" ;
1907
+
1879
1908
if (argc ) {
1880
1909
argc = parse_options (argc , argv , contention_options ,
1881
1910
contention_usage , 0 );
0 commit comments