19
19
#include "split-index.h"
20
20
#include "utf8.h"
21
21
22
+ #ifndef NO_PTHREADS
23
+ #include <pthread.h>
24
+ #endif
25
+
22
26
/* Mask for the name length in ce_flags in the on-disk index */
23
27
24
28
#define CE_NAMEMASK (0x0fff)
@@ -1390,6 +1394,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
1390
1394
return 0 ;
1391
1395
}
1392
1396
1397
+ #ifndef NO_PTHREADS
1398
+ /*
1399
+ * Require index file to be larger than this threshold before
1400
+ * we bother using a thread to verify the SHA.
1401
+ * This value was arbitrarily chosen.
1402
+ */
1403
+ #define VERIFY_HDR_THRESHOLD 10*1024*1024
1404
+
1405
+ struct verify_hdr_thread_data
1406
+ {
1407
+ pthread_t thread_id ;
1408
+ struct cache_header * hdr ;
1409
+ size_t size ;
1410
+ int result ;
1411
+ };
1412
+
1413
+ /*
1414
+ * A thread proc to run the verify_hdr() computation
1415
+ * in a background thread.
1416
+ */
1417
+ static void * verify_hdr_thread (void * _data )
1418
+ {
1419
+ struct verify_hdr_thread_data * p = _data ;
1420
+ p -> result = verify_hdr (p -> hdr , (unsigned long )p -> size );
1421
+ return NULL ;
1422
+ }
1423
+ #endif
1424
+
1393
1425
static int read_index_extension (struct index_state * istate ,
1394
1426
const char * ext , void * data , unsigned long sz )
1395
1427
{
@@ -1574,6 +1606,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1574
1606
void * mmap ;
1575
1607
size_t mmap_size ;
1576
1608
struct strbuf previous_name_buf = STRBUF_INIT , * previous_name ;
1609
+ #ifndef NO_PTHREADS
1610
+ struct verify_hdr_thread_data verify_hdr_thread_data ;
1611
+ #endif
1577
1612
1578
1613
if (istate -> initialized )
1579
1614
return istate -> cache_nr ;
@@ -1600,8 +1635,23 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1600
1635
close (fd );
1601
1636
1602
1637
hdr = mmap ;
1638
+ #ifdef NO_PTHREADS
1603
1639
if (verify_hdr (hdr , mmap_size ) < 0 )
1604
1640
goto unmap ;
1641
+ #else
1642
+ if (mmap_size < VERIFY_HDR_THRESHOLD ) {
1643
+ if (verify_hdr (hdr , mmap_size ) < 0 )
1644
+ goto unmap ;
1645
+ } else {
1646
+ verify_hdr_thread_data .hdr = hdr ;
1647
+ verify_hdr_thread_data .size = mmap_size ;
1648
+ verify_hdr_thread_data .result = -1 ;
1649
+ if (pthread_create (
1650
+ & verify_hdr_thread_data .thread_id , NULL ,
1651
+ verify_hdr_thread , & verify_hdr_thread_data ))
1652
+ die_errno ("unable to start verify_hdr_thread" );
1653
+ }
1654
+ #endif
1605
1655
1606
1656
hashcpy (istate -> sha1 , (const unsigned char * )hdr + mmap_size - 20 );
1607
1657
istate -> version = ntohl (hdr -> hdr_version );
@@ -1649,6 +1699,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1649
1699
src_offset += 8 ;
1650
1700
src_offset += extsize ;
1651
1701
}
1702
+
1703
+ #ifndef NO_PTHREADS
1704
+ if (mmap_size >= VERIFY_HDR_THRESHOLD ) {
1705
+ if (pthread_join (verify_hdr_thread_data .thread_id , NULL ))
1706
+ die_errno ("unable to join verify_hdr_thread" );
1707
+ if (verify_hdr_thread_data .result < 0 )
1708
+ goto unmap ;
1709
+ }
1710
+ #endif
1711
+
1652
1712
munmap (mmap , mmap_size );
1653
1713
return istate -> cache_nr ;
1654
1714
0 commit comments