4444 ATTRIBUTE_NAME ,
4545#elif ARCH_ARM
4646 ATTRIBUTE_SOC ,
47+ #endif
48+ #if defined(ARCH_X86 ) || defined(ARCH_ARM )
4749 ATTRIBUTE_CPU_NUM ,
4850#endif
4951 ATTRIBUTE_HYPERVISOR ,
@@ -75,6 +77,8 @@ static const char* ATTRIBUTE_FIELDS [] = {
7577 "Part Number:" ,
7678#elif ARCH_ARM
7779 "SoC:" ,
80+ #endif
81+ #if defined(ARCH_X86 ) || defined (ARCH_ARM )
7882 "" ,
7983#endif
8084 "Hypervisor:" ,
@@ -106,6 +110,8 @@ static const char* ATTRIBUTE_FIELDS_SHORT [] = {
106110 "P/N:" ,
107111#elif ARCH_ARM
108112 "SoC:" ,
113+ #endif
114+ #if defined(ARCH_X86 ) || defined (ARCH_ARM )
109115 "" ,
110116#endif
111117 "Hypervisor:" ,
@@ -424,11 +430,12 @@ uint32_t longest_field_length(struct ascii* art, int la) {
424430}
425431
426432#if defined(ARCH_X86 ) || defined(ARCH_PPC )
427- void print_ascii_generic (struct ascii * art , uint32_t la , int32_t termw , const char * * attribute_fields ) {
433+ void print_ascii_generic (struct ascii * art , uint32_t la , int32_t termw , const char * * attribute_fields , bool hybrid_architecture ) {
428434 struct ascii_logo * logo = art -> art ;
429435 int attr_to_print = 0 ;
430436 int attr_type ;
431437 char * attr_value ;
438+ int32_t beg_space ;
432439 int32_t space_right ;
433440 int32_t space_up = ((int )logo -> height - (int )art -> n_attributes_set )/2 ;
434441 int32_t space_down = (int )logo -> height - (int )art -> n_attributes_set - (int )space_up ;
@@ -439,6 +446,7 @@ void print_ascii_generic(struct ascii* art, uint32_t la, int32_t termw, const ch
439446 lbuf -> buf = emalloc (sizeof (char ) * LINE_BUFFER_SIZE );
440447 lbuf -> pos = 0 ;
441448 lbuf -> chars = 0 ;
449+ bool add_space = false;
442450
443451 printf ("\n" );
444452 for (int32_t n = 0 ; n < iters ; n ++ ) {
@@ -473,9 +481,24 @@ void print_ascii_generic(struct ascii* art, uint32_t la, int32_t termw, const ch
473481 attr_value = art -> attributes [attr_to_print ]-> value ;
474482 attr_to_print ++ ;
475483
476- space_right = 1 + (la - strlen (attribute_fields [attr_type ]));
477- printOut (lbuf , strlen (attribute_fields [attr_type ]) + space_right + strlen (attr_value ),
478- "%s%s%s%*s%s%s%s" , logo -> color_text [0 ], attribute_fields [attr_type ], art -> reset , space_right , "" , logo -> color_text [1 ], attr_value , art -> reset );
484+ if (attr_type == ATTRIBUTE_L3 ) {
485+ add_space = false;
486+ }
487+ if (attr_type == ATTRIBUTE_CPU_NUM ) {
488+ printOut (lbuf , strlen (attr_value ), "%s%s%s" , logo -> color_text [0 ], attr_value , art -> reset );
489+ add_space = true;
490+ }
491+ else {
492+ beg_space = 0 ;
493+ space_right = 2 + 1 + (la - strlen (attribute_fields [attr_type ]));
494+ if (hybrid_architecture && add_space ) {
495+ beg_space = 2 ;
496+ space_right -= 2 ;
497+ }
498+
499+ printOut (lbuf , beg_space + strlen (attribute_fields [attr_type ]) + space_right + strlen (attr_value ),
500+ "%*s%s%s%s%*s%s%s%s" , beg_space , "" , logo -> color_text [0 ], attribute_fields [attr_type ], art -> reset , space_right , "" , logo -> color_text [1 ], attr_value , art -> reset );
501+ }
479502 }
480503 printOutLine (lbuf , art , termw );
481504 printf ("\n" );
@@ -501,57 +524,71 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
501524
502525 art -> new_intel_logo = choose_new_intel_logo (cpu );
503526
504- // Step 1. Retrieve attributes (if some structures are NULL, like topo
505- // or cache, do not try to retrieve them)
506527 uint32_t socket_num = 1 ;
507528 char * l1i , * l1d , * l2 , * l3 , * n_cores , * n_cores_dual , * sockets ;
508529 l1i = l1d = l2 = l3 = n_cores = n_cores_dual = sockets = NULL ;
509530
510- char * uarch = get_str_uarch (cpu );
511- char * manufacturing_process = get_str_process (cpu );
512- char * max_frequency = get_str_freq (cpu -> freq );
513531 char * cpu_name = get_str_cpu_name (cpu , fcpuname );
514- char * avx = get_str_avx (cpu );
515- char * fma = get_str_fma (cpu );
532+ char * uarch = get_str_uarch (cpu );
516533 char * pp = get_str_peak_performance (cpu -> peak_performance );
517-
518- if (cpu -> topo != NULL ) {
519- sockets = get_str_sockets (cpu -> topo );
520- n_cores = get_str_topology (cpu , cpu -> topo , false);
521- n_cores_dual = get_str_topology (cpu , cpu -> topo , true);
522- }
534+ char * manufacturing_process = get_str_process (cpu );
535+ bool hybrid_architecture = cpu -> next_cpu != NULL ;
523536
524537 if (cpu -> cach != NULL ) {
525- l1i = get_str_l1i (cpu -> cach );
526- l1d = get_str_l1d (cpu -> cach );
527- l2 = get_str_l2 (cpu -> cach );
528538 l3 = get_str_l3 (cpu -> cach );
529539 }
530540
531- // Step 2. Set attributes
532541 setAttribute (art , ATTRIBUTE_NAME , cpu_name );
533542 if (cpu -> hv -> present ) {
534543 setAttribute (art , ATTRIBUTE_HYPERVISOR , cpu -> hv -> hv_name );
535544 }
536545 setAttribute (art , ATTRIBUTE_UARCH , uarch );
537546 setAttribute (art , ATTRIBUTE_TECHNOLOGY , manufacturing_process );
538- setAttribute (art , ATTRIBUTE_FREQUENCY , max_frequency );
539- if (cpu -> topo != NULL ) {
540- socket_num = get_nsockets (cpu -> topo );
541- if (socket_num > 1 ) {
542- setAttribute (art , ATTRIBUTE_SOCKETS , sockets );
543- setAttribute (art , ATTRIBUTE_NCORES , n_cores );
544- setAttribute (art , ATTRIBUTE_NCORES_DUAL , n_cores_dual );
547+
548+ struct cpuInfo * ptr = cpu ;
549+ for (int i = 0 ; i < cpu -> num_cpus ; ptr = ptr -> next_cpu , i ++ ) {
550+ char * max_frequency = get_str_freq (ptr -> freq );
551+ char * avx = get_str_avx (ptr );
552+ char * fma = get_str_fma (ptr );
553+ char * cpu_num = emalloc (sizeof (char ) * 9 );
554+
555+ if (ptr -> topo != NULL ) {
556+ sockets = get_str_sockets (ptr -> topo );
557+ n_cores = get_str_topology (ptr , ptr -> topo , false);
558+ n_cores_dual = get_str_topology (ptr , ptr -> topo , true);
545559 }
546- else {
547- setAttribute (art , ATTRIBUTE_NCORES , n_cores );
560+
561+ if (ptr -> cach != NULL ) {
562+ l1i = get_str_l1i (ptr -> cach );
563+ l1d = get_str_l1d (ptr -> cach );
564+ l2 = get_str_l2 (ptr -> cach );
565+ }
566+
567+ if (hybrid_architecture ) {
568+ if (ptr -> core_type == CORE_TYPE_EFFICIENCY ) sprintf (cpu_num , "E-cores:" );
569+ else if (ptr -> core_type == CORE_TYPE_PERFORMANCE ) sprintf (cpu_num , "P-cores:" );
570+ else printBug ("Found invalid core type!\n" );
571+
572+ setAttribute (art , ATTRIBUTE_CPU_NUM , cpu_num );
548573 }
574+ setAttribute (art , ATTRIBUTE_FREQUENCY , max_frequency );
575+ if (ptr -> topo != NULL ) {
576+ socket_num = get_nsockets (ptr -> topo );
577+ if (socket_num > 1 ) {
578+ setAttribute (art , ATTRIBUTE_SOCKETS , sockets );
579+ setAttribute (art , ATTRIBUTE_NCORES , n_cores );
580+ setAttribute (art , ATTRIBUTE_NCORES_DUAL , n_cores_dual );
581+ }
582+ else {
583+ setAttribute (art , ATTRIBUTE_NCORES , n_cores );
584+ }
585+ }
586+ setAttribute (art , ATTRIBUTE_AVX , avx );
587+ setAttribute (art , ATTRIBUTE_FMA , fma );
588+ if (l1i != NULL ) setAttribute (art , ATTRIBUTE_L1i , l1i );
589+ if (l1d != NULL ) setAttribute (art , ATTRIBUTE_L1d , l1d );
590+ if (l2 != NULL ) setAttribute (art , ATTRIBUTE_L2 , l2 );
549591 }
550- setAttribute (art , ATTRIBUTE_AVX , avx );
551- setAttribute (art , ATTRIBUTE_FMA , fma );
552- if (l1i != NULL ) setAttribute (art , ATTRIBUTE_L1i , l1i );
553- if (l1d != NULL ) setAttribute (art , ATTRIBUTE_L1d , l1d );
554- if (l2 != NULL ) setAttribute (art , ATTRIBUTE_L2 , l2 );
555592 if (l3 != NULL ) setAttribute (art , ATTRIBUTE_L3 , l3 );
556593 setAttribute (art , ATTRIBUTE_PEAK , pp );
557594
@@ -568,15 +605,12 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
568605 longest_attribute = longest_attribute_length (art , attribute_fields );
569606 }
570607
571- print_ascii_generic (art , longest_attribute , term -> w , attribute_fields );
608+ print_ascii_generic (art , longest_attribute , term -> w , attribute_fields , hybrid_architecture );
572609
573610 free (manufacturing_process );
574- free (max_frequency );
575611 free (sockets );
576612 free (n_cores );
577613 free (n_cores_dual );
578- free (avx );
579- free (fma );
580614 free (l1i );
581615 free (l1d );
582616 free (l2 );
0 commit comments