24
24
* - Move integrity and poison checking to separate file
25
25
* R.Hempel 2017-12-29 - Fix bug in realloc when requesting a new block that
26
26
* results in OOM error - see Issue 11
27
+ * R.Hempel 2019-09-07 - Separate the malloc() and free() functionality into
28
+ * wrappers that use critical section protection macros
29
+ * and static core functions that assume they are
30
+ * running in a protected con text. Thanks @devyte
27
31
* ----------------------------------------------------------------------------
28
32
*/
29
33
@@ -367,22 +371,15 @@ void umm_init( void ) {
367
371
}
368
372
}
369
373
370
- /* ------------------------------------------------------------------------ */
374
+ /* ------------------------------------------------------------------------
375
+ * Must be called only from within critical sections guarded by
376
+ * UMM_CRITICAL_ENTRY() and UMM_CRITICAL_EXIT().
377
+ */
371
378
372
- void umm_free ( void *ptr ) {
373
- UMM_CRITICAL_DECL (id_free);
379
+ static void umm_free_core ( void *ptr ) {
374
380
375
381
unsigned short int c;
376
382
377
- /* If we're being asked to free a NULL pointer, well that's just silly! */
378
-
379
- if ( (void *)0 == ptr ) {
380
- DBGLOG_DEBUG ( " free a null pointer -> do nothing\n " );
381
- STATS__NULL_FREE_REQUEST (id_free);
382
-
383
- return ;
384
- }
385
-
386
383
STATS__FREE_REQUEST (id_free);
387
384
/*
388
385
* FIXME: At some point it might be a good idea to add a check to make sure
@@ -399,9 +396,6 @@ void umm_free( void *ptr ) {
399
396
400
397
DBGLOG_DEBUG ( " Freeing block %6d\n " , c );
401
398
402
- /* Protect the critical section... */
403
- UMM_CRITICAL_ENTRY (id_free);
404
-
405
399
/* Update stats Free Block count */
406
400
STATS__FREE_BLOCKS_UPDATE (UMM_NBLOCK (c) - c);
407
401
@@ -431,50 +425,53 @@ void umm_free( void *ptr ) {
431
425
432
426
UMM_NBLOCK (c) |= UMM_FREELIST_MASK;
433
427
}
434
-
435
- /* Release the critical section... */
436
- UMM_CRITICAL_EXIT (id_free);
437
428
}
438
429
439
430
/* ------------------------------------------------------------------------ */
440
431
441
- void * umm_malloc ( size_t size ) {
442
- UMM_CRITICAL_DECL (id_malloc );
432
+ void umm_free ( void *ptr ) {
433
+ UMM_CRITICAL_DECL (id_free );
443
434
444
- unsigned short int blocks;
445
- unsigned short int blockSize = 0 ;
435
+ if (umm_heap == NULL ) {
436
+ umm_init ();
437
+ }
446
438
447
- unsigned short int bestSize;
448
- unsigned short int bestBlock;
439
+ /* If we're being asked to free a NULL pointer, well that's just silly! */
449
440
450
- unsigned short int cf;
441
+ if ( (void *)0 == ptr ) {
442
+ DBGLOG_DEBUG ( " free a null pointer -> do nothing\n " );
443
+ STATS__NULL_FREE_REQUEST (id_free);
451
444
452
- if (umm_heap == NULL ) {
453
- umm_init ();
445
+ return ;
454
446
}
455
447
456
- /*
457
- * the very first thing we do is figure out if we're being asked to allocate
458
- * a size of 0 - and if we are we'll simply return a null pointer. if not
459
- * then reduce the size by 1 byte so that the subsequent calculations on
460
- * the number of blocks to allocate are easier...
461
- */
448
+ /* Free the memory withing a protected critical section */
462
449
450
+ UMM_CRITICAL_ENTRY (id_free);
463
451
464
- if ( 0 == size ) {
465
- DBGLOG_DEBUG ( " malloc a block of 0 bytes -> do nothing\n " );
466
- STATS__ZERO_ALLOC_REQUEST (id_malloc, size);
452
+ umm_free_core ( ptr );
467
453
468
- return ( (void *)NULL );
469
- }
454
+ UMM_CRITICAL_EXIT (id_free);
455
+ }
456
+
457
+ /* ------------------------------------------------------------------------
458
+ * Must be called only from within critical sections guarded by
459
+ * UMM_CRITICAL_ENTRY() and UMM_CRITICAL_EXIT().
460
+ */
461
+
462
+ static void *umm_malloc_core ( size_t size ) {
463
+ unsigned short int blocks;
464
+ unsigned short int blockSize = 0 ;
465
+
466
+ unsigned short int bestSize;
467
+ unsigned short int bestBlock;
468
+
469
+ unsigned short int cf;
470
470
471
471
STATS__ALLOC_REQUEST (id_malloc, size);
472
472
473
473
blocks = umm_blocks ( size );
474
474
475
- /* Protect the critical section... */
476
- UMM_CRITICAL_ENTRY (id_malloc);
477
-
478
475
/*
479
476
* Now we can scan through the free list until we find a space that's big
480
477
* enough to hold the number of blocks we need.
@@ -566,16 +563,46 @@ void *umm_malloc( size_t size ) {
566
563
567
564
DBGLOG_DEBUG ( " Can't allocate %5d blocks\n " , blocks );
568
565
569
- /* Release the critical section... */
570
- UMM_CRITICAL_EXIT (id_malloc);
571
-
572
566
return ( (void *)NULL );
573
567
}
574
568
575
- /* Release the critical section... */
569
+ return ( (void *)&UMM_DATA (cf) );
570
+ }
571
+
572
+ /* ------------------------------------------------------------------------ */
573
+
574
+ void *umm_malloc ( size_t size ) {
575
+ UMM_CRITICAL_DECL (id_malloc);
576
+
577
+ void *ptr = NULL ;
578
+
579
+ if (umm_heap == NULL ) {
580
+ umm_init ();
581
+ }
582
+
583
+ /*
584
+ * the very first thing we do is figure out if we're being asked to allocate
585
+ * a size of 0 - and if we are we'll simply return a null pointer. if not
586
+ * then reduce the size by 1 byte so that the subsequent calculations on
587
+ * the number of blocks to allocate are easier...
588
+ */
589
+
590
+ if ( 0 == size ) {
591
+ DBGLOG_DEBUG ( " malloc a block of 0 bytes -> do nothing\n " );
592
+ STATS__ZERO_ALLOC_REQUEST (id_malloc, size);
593
+
594
+ return ( ptr );
595
+ }
596
+
597
+ /* Allocate the memory withing a protected critical section */
598
+
599
+ UMM_CRITICAL_ENTRY (id_malloc);
600
+
601
+ ptr = umm_malloc_core ( size );
602
+
576
603
UMM_CRITICAL_EXIT (id_malloc);
577
604
578
- return ( ( void *)& UMM_DATA (cf) );
605
+ return ( ptr );
579
606
}
580
607
581
608
/* ------------------------------------------------------------------------ */
@@ -724,7 +751,7 @@ void *umm_realloc( void *ptr, size_t size ) {
724
751
#ifdef UMM_LIGHTWEIGHT_CPU
725
752
if ((prevBlockSize + blockSize + nextBlockSize) > blocks) {
726
753
umm_split_block ( c, blocks, 0 );
727
- umm_free ( (void *)&UMM_DATA (c+blocks) );
754
+ umm_free_core ( (void *)&UMM_DATA (c+blocks) );
728
755
}
729
756
STATS__FREE_BLOCKS_ISR_MIN ();
730
757
blockSize = blocks;
@@ -736,19 +763,18 @@ void *umm_realloc( void *ptr, size_t size ) {
736
763
ptr = (void *)&UMM_DATA (c);
737
764
UMM_CRITICAL_RESUME (id_realloc);
738
765
} else {
739
- UMM_CRITICAL_SUSPEND (id_realloc);
740
766
DBGLOG_DEBUG ( " realloc a completely new block %i\n " , blocks );
741
767
void *oldptr = ptr;
742
- if ( (ptr = umm_malloc ( size )) ) {
768
+ if ( (ptr = umm_malloc_core ( size )) ) {
743
769
DBGLOG_DEBUG ( " realloc %i to a bigger block %i, copy, and free the old\n " , blockSize, blocks );
770
+ UMM_CRITICAL_SUSPEND (id_realloc);
744
771
memcpy ( ptr, oldptr, curSize );
745
- umm_free ( oldptr );
746
- blockSize = blocks;
747
772
UMM_CRITICAL_RESUME (id_realloc);
773
+ umm_free_core ( oldptr );
774
+ blockSize = blocks;
748
775
} else {
749
776
DBGLOG_DEBUG ( " realloc %i to a bigger block %i failed - return NULL and leave the old block!\n " , blockSize, blocks );
750
777
/* This space intentionally left blnk */
751
- UMM_CRITICAL_RESUME (id_realloc);
752
778
STATS__OOM_UPDATE ();
753
779
}
754
780
}
@@ -794,7 +820,7 @@ void *umm_realloc( void *ptr, size_t size ) {
794
820
#ifdef UMM_LIGHTWEIGHT_CPU
795
821
if (blockSize > blocks) {
796
822
umm_split_block ( c, blocks, 0 );
797
- umm_free ( (void *)&UMM_DATA (c+blocks) );
823
+ umm_free_core ( (void *)&UMM_DATA (c+blocks) );
798
824
}
799
825
STATS__FREE_BLOCKS_ISR_MIN ();
800
826
blockSize = blocks;
@@ -813,19 +839,18 @@ void *umm_realloc( void *ptr, size_t size ) {
813
839
STATS__FREE_BLOCKS_UPDATE (-nextBlockSize);
814
840
blockSize += nextBlockSize;
815
841
} else { // 4
816
- UMM_CRITICAL_SUSPEND (id_realloc);
817
842
DBGLOG_DEBUG ( " realloc a completely new block %d\n " , blocks );
818
843
void *oldptr = ptr;
819
- if ( (ptr = umm_malloc ( size )) ) {
844
+ if ( (ptr = umm_malloc_core ( size )) ) {
820
845
DBGLOG_DEBUG ( " realloc %d to a bigger block %d, copy, and free the old\n " , blockSize, blocks );
846
+ UMM_CRITICAL_SUSPEND (id_realloc);
821
847
memcpy ( ptr, oldptr, curSize );
822
- umm_free ( oldptr);
823
- blockSize = blocks;
824
848
UMM_CRITICAL_RESUME (id_realloc);
849
+ umm_free_core ( oldptr);
850
+ blockSize = blocks;
825
851
} else {
826
852
DBGLOG_DEBUG ( " realloc %d to a bigger block %d failed - return NULL and leave the old block!\n " , blockSize, blocks );
827
853
/* This space intentionally left blnk */
828
- UMM_CRITICAL_RESUME (id_realloc);
829
854
STATS__OOM_UPDATE ();
830
855
}
831
856
}
@@ -836,15 +861,15 @@ void *umm_realloc( void *ptr, size_t size ) {
836
861
DBGLOG_DEBUG ( " realloc the same or smaller size block - %d, do nothing\n " , blocks );
837
862
/* This space intentionally left blank */
838
863
} else {
839
- UMM_CRITICAL_SUSPEND (id_realloc);
840
864
DBGLOG_DEBUG ( " realloc a completely new block %d\n " , blocks );
841
865
void *oldptr = ptr;
842
- if ( (ptr = umm_malloc ( size )) ) {
866
+ if ( (ptr = umm_malloc_core ( size )) ) {
843
867
DBGLOG_DEBUG ( " realloc %d to a bigger block %d, copy, and free the old\n " , blockSize, blocks );
868
+ UMM_CRITICAL_SUSPEND (id_realloc);
844
869
memcpy ( ptr, oldptr, curSize );
845
- umm_free ( oldptr );
846
- blockSize = blocks;
847
870
UMM_CRITICAL_RESUME (id_realloc);
871
+ umm_free_core ( oldptr );
872
+ blockSize = blocks;
848
873
} else {
849
874
DBGLOG_DEBUG ( " realloc %d to a bigger block %d failed - return NULL and leave the old block!\n " , blockSize, blocks );
850
875
/* This space intentionally left blnk */
@@ -860,7 +885,7 @@ void *umm_realloc( void *ptr, size_t size ) {
860
885
if (blockSize > blocks ) {
861
886
DBGLOG_DEBUG ( " split and free %d blocks from %d\n " , blocks, blockSize );
862
887
umm_split_block ( c, blocks, 0 );
863
- umm_free ( (void *)&UMM_DATA (c+blocks) );
888
+ umm_free_core ( (void *)&UMM_DATA (c+blocks) );
864
889
}
865
890
866
891
STATS__FREE_BLOCKS_MIN ();
0 commit comments