4949#include <stdint.h>
5050#include <string.h>
5151
52-
52+ // Frequency of sampling
53+ #ifndef GMON_HZ
54+ #define GMON_HZ 10000
55+ #endif
5356
5457/*
5558 fraction of text space to allocate for histogram counters here, 1/2
5659*/
60+ #ifndef HISTFRACTION
5761#define HISTFRACTION 8
62+ #endif
5863
5964/*
6065 Fraction of text space to allocate for from hash buckets.
8489 profiling data structures without (in practice) sacrificing
8590 any granularity.
8691*/
92+ #ifndef HASHFRACTION
8793#define HASHFRACTION 2
94+ #endif
8895
8996/*
9097 percent of text space to allocate for tostructs with a minimum.
9198*/
99+ #ifndef ARCDENSITY
92100#define ARCDENSITY 2 /* this is in percentage, relative to text size! */
101+ #endif
93102#define MINARCS 50
94103#define MAXARCS ((1 << (8 * sizeof(HISTCOUNTER))) - 2)
95104
101110#define GMON_PROF_ERROR 2
102111#define GMON_PROF_OFF 3
103112
104- void _mcleanup (void ); /* routine to be called to write gmon.out file */
113+ // void _mcleanup(void); /* routine to be called to write gmon.out file */
105114
106115
107116
@@ -195,7 +204,6 @@ static struct profinfo prof = {
195204 PROFILE_NOT_INIT , 0 , 0 , 0 , 0
196205};
197206extern volatile bool __otherCoreIdled ;
198- static int __profileHz = 0 ;
199207
200208/* convert an addr to an index */
201209#define PROFIDX (pc , base , scale ) \
@@ -290,22 +298,17 @@ int __no_inline_not_in_flash_func(profil)(char *samples, size_t size, size_t off
290298#define PICO_RUNTIME_INIT_PROFILING "11011" // Towards the end, after PSRAM
291299#if defined(__riscv )
292300void runtime_init_setup_profiling () {
293- __profileHz = 10000 ;
294301 // TODO - is there an equivalent? Or do we need to build a timer IRQ here?
295302}
296303#else
297304#include <hardware/exception.h>
298305#include <hardware/structs/systick.h>
299306void runtime_init_setup_profiling () {
300- __profileHz = 10000 ;
301307 exception_set_exclusive_handler (SYSTICK_EXCEPTION , _SystickHandler );
302308 systick_hw -> csr = 0x7 ;
303- systick_hw -> rvr = (F_CPU / __profileHz ) - 1 ;
309+ systick_hw -> rvr = (F_CPU / GMON_HZ ) - 1 ;
304310}
305311#endif
306- #ifdef __PROFILE
307- PICO_RUNTIME_INIT_FUNC_RUNTIME (runtime_init_setup_profiling , PICO_RUNTIME_INIT_PROFILING );
308- #endif
309312
310313
311314#define MINUS_ONE_P (-1)
@@ -393,54 +396,28 @@ void __no_inline_not_in_flash_func(monstartup)(size_t lowpc, size_t highpc) {
393396#ifndef O_BINARY
394397#define O_BINARY 0
395398#endif
396- extern int __profileHz ;
397399
398- void _mcleanup (void ) {
399- static const char gmon_out [] = "gmon.out" ;
400- int fd ;
401- int hz ;
400+ // Ensure matches definition in rp2040support
401+ typedef int (* profileWriteCB )(const void * data , int len );
402+ void _writeProfile (profileWriteCB writeCB ) {
402403 int fromindex ;
403404 int endfrom ;
404405 size_t frompc ;
405406 int toindex ;
406407 struct rawarc rawarc ;
407408 struct gmonparam * p = & _gmonparam ;
408409 struct gmonhdr gmonhdr , * hdr ;
409- const char * proffile ;
410- #ifdef DEBUG
411- int log , len ;
412- char dbuf [200 ];
413- #endif
414410
415- if (p -> state == GMON_PROF_ERROR ) {
416- ERR ("_mcleanup: tos overflow\n" );
417- }
418- hz = __profileHz ;//PROF_HZ;
419411 moncontrol (0 ); /* stop */
420- proffile = gmon_out ;
421- fd = open (proffile , O_CREAT | O_TRUNC | O_WRONLY | O_BINARY , 0666 );
422- if (fd < 0 ) {
423- perror (proffile );
424- return ;
425- }
426- #ifdef DEBUG
427- log = open ("gmon.log" , O_CREAT | O_TRUNC | O_WRONLY , 0664 );
428- if (log < 0 ) {
429- perror ("mcount: gmon.log" );
430- return ;
431- }
432- len = sprintf (dbuf , "[mcleanup1] kcount 0x%x ssiz %d\n" ,
433- p -> kcount , p -> kcountsize );
434- write (log , dbuf , len );
435- #endif
412+
436413 hdr = (struct gmonhdr * )& gmonhdr ;
437414 hdr -> lpc = p -> lowpc ;
438415 hdr -> hpc = p -> highpc ;
439416 hdr -> ncnt = p -> kcountsize + sizeof (gmonhdr );
440417 hdr -> version = GMONVERSION ;
441- hdr -> profrate = hz ;
442- write ( fd , ( char * )hdr , sizeof * hdr );
443- write ( fd , p -> kcount , p -> kcountsize );
418+ hdr -> profrate = GMON_HZ ;
419+ writeCB (( void * )hdr , sizeof * hdr );
420+ writeCB (( void * ) p -> kcount , p -> kcountsize );
444421 endfrom = p -> fromssize / sizeof (* p -> froms );
445422 for (fromindex = 0 ; fromindex < endfrom ; fromindex ++ ) {
446423 if (p -> froms [fromindex ] == 0 ) {
@@ -449,20 +426,12 @@ void _mcleanup(void) {
449426 frompc = p -> lowpc ;
450427 frompc += fromindex * HASHFRACTION * sizeof (* p -> froms );
451428 for (toindex = p -> froms [fromindex ]; toindex != 0 ; toindex = p -> tos [toindex ].link ) {
452- #ifdef DEBUG
453- len = sprintf (dbuf ,
454- "[mcleanup2] frompc 0x%x selfpc 0x%x count %d\n" ,
455- frompc , p -> tos [toindex ].selfpc ,
456- p -> tos [toindex ].count );
457- write (log , dbuf , len );
458- #endif
459429 rawarc .raw_frompc = frompc ;
460430 rawarc .raw_selfpc = GETSELFPC (& p -> tos [toindex ]);
461431 rawarc .raw_count = GETCOUNT (& p -> tos [toindex ]);
462- write ( fd , & rawarc , sizeof rawarc );
432+ writeCB (( void * ) & rawarc , sizeof rawarc );
463433 }
464434 }
465- close (fd );
466435}
467436
468437/*
0 commit comments