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)
@@ -1393,6 +1397,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
1393
1397
return 0 ;
1394
1398
}
1395
1399
1400
+ #ifndef NO_PTHREADS
1401
+ /*
1402
+ * Require index file to be larger than this threshold before
1403
+ * we bother using a thread to verify the SHA.
1404
+ * This value was arbitrarily chosen.
1405
+ */
1406
+ #define VERIFY_HDR_THRESHOLD 10*1024*1024
1407
+
1408
+ struct verify_hdr_thread_data
1409
+ {
1410
+ pthread_t thread_id ;
1411
+ struct cache_header * hdr ;
1412
+ size_t size ;
1413
+ int result ;
1414
+ };
1415
+
1416
+ /*
1417
+ * A thread proc to run the verify_hdr() computation
1418
+ * in a background thread.
1419
+ */
1420
+ static void * verify_hdr_thread (void * _data )
1421
+ {
1422
+ struct verify_hdr_thread_data * p = _data ;
1423
+ p -> result = verify_hdr (p -> hdr , (unsigned long )p -> size );
1424
+ return NULL ;
1425
+ }
1426
+ #endif
1427
+
1396
1428
static int read_index_extension (struct index_state * istate ,
1397
1429
const char * ext , void * data , unsigned long sz )
1398
1430
{
@@ -1581,6 +1613,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1581
1613
void * mmap ;
1582
1614
size_t mmap_size ;
1583
1615
struct strbuf previous_name_buf = STRBUF_INIT , * previous_name ;
1616
+ #ifndef NO_PTHREADS
1617
+ struct verify_hdr_thread_data verify_hdr_thread_data ;
1618
+ #endif
1584
1619
1585
1620
if (istate -> initialized )
1586
1621
return istate -> cache_nr ;
@@ -1607,8 +1642,23 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1607
1642
close (fd );
1608
1643
1609
1644
hdr = mmap ;
1645
+ #ifdef NO_PTHREADS
1610
1646
if (verify_hdr (hdr , mmap_size ) < 0 )
1611
1647
goto unmap ;
1648
+ #else
1649
+ if (mmap_size < VERIFY_HDR_THRESHOLD ) {
1650
+ if (verify_hdr (hdr , mmap_size ) < 0 )
1651
+ goto unmap ;
1652
+ } else {
1653
+ verify_hdr_thread_data .hdr = hdr ;
1654
+ verify_hdr_thread_data .size = mmap_size ;
1655
+ verify_hdr_thread_data .result = -1 ;
1656
+ if (pthread_create (
1657
+ & verify_hdr_thread_data .thread_id , NULL ,
1658
+ verify_hdr_thread , & verify_hdr_thread_data ))
1659
+ die_errno ("unable to start verify_hdr_thread" );
1660
+ }
1661
+ #endif
1612
1662
1613
1663
hashcpy (istate -> sha1 , (const unsigned char * )hdr + mmap_size - 20 );
1614
1664
istate -> version = ntohl (hdr -> hdr_version );
@@ -1656,6 +1706,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
1656
1706
src_offset += 8 ;
1657
1707
src_offset += extsize ;
1658
1708
}
1709
+
1710
+ #ifndef NO_PTHREADS
1711
+ if (mmap_size >= VERIFY_HDR_THRESHOLD ) {
1712
+ if (pthread_join (verify_hdr_thread_data .thread_id , NULL ))
1713
+ die_errno ("unable to join verify_hdr_thread" );
1714
+ if (verify_hdr_thread_data .result < 0 )
1715
+ goto unmap ;
1716
+ }
1717
+ #endif
1718
+
1659
1719
munmap (mmap , mmap_size );
1660
1720
return istate -> cache_nr ;
1661
1721
0 commit comments