Loading...
pthreads/pthread.c Libc-262.3.2 Libc-262
--- Libc/Libc-262.3.2/pthreads/pthread.c
+++ Libc/Libc-262/pthreads/pthread.c
@@ -1292,6 +1292,7 @@
 #define kHasAltivec     0x01                                            
 #define kCache32                0x04                                    
 #define kUseDcba                0x20                                    
+#define kNoDcba         0x40                                            
 
 static int
 pthread_init(void)
@@ -1307,9 +1308,10 @@
 	mach_msg_type_number_t count;
 	int mib[2];
 	size_t len;
-	int numcpus;
+	int hasvectorunit, numcpus;
                                                                                 
 	extern  int     _bcopy_initialize(void);
+	int     dynamic_choice;
                                                                                 
 
         count = HOST_PRIORITY_INFO_COUNT;
@@ -1357,11 +1359,20 @@
 	}
 	mach_port_deallocate(mach_task_self(), host);
 
-	len = sizeof(_cpu_capabilities);
-	sysctlbyname("hw._cpu_capabilities", &_cpu_capabilities, &len, NULL, 0);
-
-	_bcopy_initialize();
-
+	mib[0] = CTL_HW;
+	mib[1] = HW_VECTORUNIT;
+	len = sizeof(hasvectorunit);
+	if (sysctl(mib, 2, &hasvectorunit, &len, NULL, 0) == 0) {
+		_cpu_has_altivec = hasvectorunit;
+	}
+	if (_cpu_has_altivec) {                                 // G4, let bcopy decide whether to use dcba                                        
+		_cpu_capabilities = kCache32 + kHasAltivec;                     
+	} else {                                                         // G3, no altivec and no dcba                                              
+		_cpu_capabilities = kCache32 + kNoDcba;                         
+	}                                                                       
+                                                                                
+	dynamic_choice = _bcopy_initialize();           // returns 0, kUseDcba, or kNoDcba                                                    
+	_cpu_capabilities |= dynamic_choice;            // remember dynamic choice, if any                                                                  
 	mig_init(1);		/* enable multi-threaded mig interfaces */
 	return 0;
 }