Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/malloc.c

    r21799398 r6aeca0d  
    200200        do { \
    201201                if (!(expr)) {\
    202                         futex_up(&malloc_futex); \
     202                        heap_unlock(); \
    203203                        assert_abort(#expr, __FILE__, __LINE__); \
    204204                } \
     
    210210
    211211#endif /* NDEBUG */
     212
     213
     214#ifdef FUTEX_UPGRADABLE
     215/** True if the heap may be accessed from multiple threads. */
     216static bool multithreaded = false;
     217
     218/** Makes accesses to the heap thread safe. */
     219void malloc_enable_multithreaded(void)
     220{
     221        multithreaded = true;
     222}
     223
     224/** Serializes access to the heap from multiple threads. */
     225static inline void heap_lock(void)
     226{
     227        if (multithreaded) {
     228                futex_down(&malloc_futex);
     229        } else {
     230                /*
     231                 * Malloc never switches fibrils while the heap is locked.
     232                 * Similarly, it never creates new threads from within the
     233                 * locked region. Therefore, if there are no other threads
     234                 * except this one, the whole operation will complete without
     235                 * any interruptions.
     236                 */
     237        }
     238}
     239
     240/** Serializes access to the heap from multiple threads. */
     241static inline void heap_unlock(void)
     242{
     243        if (multithreaded) {
     244                futex_up(&malloc_futex);
     245        } else {
     246                /*
     247                 * Malloc never switches fibrils while the heap is locked.
     248                 * Similarly, it never creates new threads from within the
     249                 * locked region. Therefore, if there are no other threads
     250                 * except this one, the whole operation will complete without
     251                 * any interruptions.
     252                 */
     253        }
     254}
     255
     256#else
     257
     258/** Makes accesses to the heap thread safe. */
     259void malloc_enable_multithreaded(void)
     260{
     261        /* No-op. Already using thread-safe heap locking operations. */
     262}
     263
     264/** Serializes access to the heap from multiple threads. */
     265static inline void heap_lock(void)
     266{
     267        futex_down(&malloc_futex);
     268}
     269
     270/** Serializes access to the heap from multiple threads. */
     271static inline void heap_unlock(void)
     272{
     273        futex_up(&malloc_futex);
     274}
     275#endif
     276
    212277
    213278/** Initialize a heap block
     
    289354        size_t asize = ALIGN_UP(size, PAGE_SIZE);
    290355        void *astart = as_area_create(AS_AREA_ANY, asize,
    291             AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
     356            AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
    292357        if (astart == AS_MAP_FAILED)
    293358                return false;
     
    785850void *malloc(const size_t size)
    786851{
    787         futex_down(&malloc_futex);
     852        heap_lock();
    788853        void *block = malloc_internal(size, BASE_ALIGN);
    789         futex_up(&malloc_futex);
    790        
     854        heap_unlock();
     855
    791856        return block;
    792857}
     
    807872        size_t palign =
    808873            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    809        
    810         futex_down(&malloc_futex);
     874
     875        heap_lock();
    811876        void *block = malloc_internal(size, palign);
    812         futex_up(&malloc_futex);
    813        
     877        heap_unlock();
     878
    814879        return block;
    815880}
     
    828893                return malloc(size);
    829894       
    830         futex_down(&malloc_futex);
     895        heap_lock();
    831896       
    832897        /* Calculate the position of the header. */
     
    885950        }
    886951       
    887         futex_up(&malloc_futex);
     952        heap_unlock();
    888953       
    889954        if (reloc) {
     
    908973                return;
    909974       
    910         futex_down(&malloc_futex);
     975        heap_lock();
    911976       
    912977        /* Calculate the position of the header. */
     
    9531018        heap_shrink(area);
    9541019       
    955         futex_up(&malloc_futex);
     1020        heap_unlock();
    9561021}
    9571022
    9581023void *heap_check(void)
    9591024{
    960         futex_down(&malloc_futex);
     1025        heap_lock();
    9611026       
    9621027        if (first_heap_area == NULL) {
    963                 futex_up(&malloc_futex);
     1028                heap_unlock();
    9641029                return (void *) -1;
    9651030        }
     
    9751040                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
    9761041                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
    977                         futex_up(&malloc_futex);
     1042                        heap_unlock();
    9781043                        return (void *) area;
    9791044                }
     
    9861051                        /* Check heap block consistency */
    9871052                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
    988                                 futex_up(&malloc_futex);
     1053                                heap_unlock();
    9891054                                return (void *) head;
    9901055                        }
     
    9941059                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
    9951060                            (head->size != foot->size)) {
    996                                 futex_up(&malloc_futex);
     1061                                heap_unlock();
    9971062                                return (void *) foot;
    9981063                        }
     
    10001065        }
    10011066       
    1002         futex_up(&malloc_futex);
     1067        heap_unlock();
    10031068       
    10041069        return NULL;
Note: See TracChangeset for help on using the changeset viewer.