Changeset 9d47440 in mainline for uspace/lib/c


Ignore:
Timestamp:
2011-05-21T16:23:17Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0ff03f3
Parents:
8d308b9 (diff), 13f2461 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/lib/c
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r8d308b9 r9d47440  
    108108        generic/adt/measured_strings.c \
    109109        generic/adt/char_map.c \
     110        generic/adt/prodcons.c \
    110111        generic/time.c \
    111112        generic/stdlib.c \
  • uspace/lib/c/generic/assert.c

    r8d308b9 r9d47440  
    3333#include <assert.h>
    3434#include <stdio.h>
     35#include <io/klog.h>
    3536#include <stdlib.h>
     37#include <atomic.h>
    3638#include <stacktrace.h>
    3739
    38 void assert_abort(const char *cond, const char *file, unsigned int line)
     40#define MSG_START       "Assertion failed ("
     41#define MSG_FILE        ") in file \""
     42#define MSG_LINE        "\", line "
     43#define MSG_END         ".\n"
     44
     45static atomic_t failed_asserts;
     46
     47void assert_abort(const char *cond, const char *file, const char *line)
    3948{
    40         printf("Assertion failed (%s) in file \"%s\", line %u.\n",
     49        /*
     50         * Send the message safely to klog. Nested asserts should not occur.
     51         */
     52        klog_write(MSG_START, str_size(MSG_START));
     53        klog_write(cond, str_size(cond));
     54        klog_write(MSG_FILE, str_size(MSG_FILE));
     55        klog_write(file, str_size(file));
     56        klog_write(MSG_LINE, str_size(MSG_LINE));
     57        klog_write(line, str_size(line));
     58        klog_write(MSG_END, str_size(MSG_END));
     59
     60        /*
     61         * Check if this is a nested or parallel assert.
     62         */
     63        if (atomic_postinc(&failed_asserts))
     64                abort();
     65       
     66        /*
     67         * Attempt to print the message to standard output and display
     68         * the stack trace. These operations can theoretically trigger nested
     69         * assertions.
     70         */
     71        printf(MSG_START "%s" MSG_FILE "%s" MSG_LINE "%s" MSG_END,
    4172            cond, file, line);
    4273        stacktrace_print();
     74
    4375        abort();
    4476}
  • uspace/lib/c/generic/event.c

    r8d308b9 r9d47440  
    4141#include <kernel/ipc/event_types.h>
    4242
    43 /** Subscribe for event notifications.
     43/** Subscribe event notifications.
    4444 *
    45  * @param evno   Event number.
    46  * @param method Use this method for notifying me.
     45 * @param evno    Event type to subscribe.
     46 * @param imethod Use this interface and method for notifying me.
    4747 *
    4848 * @return Value returned by the kernel.
     49 *
    4950 */
    50 int event_subscribe(event_type_t e, sysarg_t method)
     51int event_subscribe(event_type_t evno, sysarg_t imethod)
    5152{
    52         return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method);
     53        return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno,
     54            (sysarg_t) imethod);
     55}
     56
     57/** Unmask event notifications.
     58 *
     59 * @param evno Event type to unmask.
     60 *
     61 * @return Value returned by the kernel.
     62 *
     63 */
     64int event_unmask(event_type_t evno)
     65{
     66        return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno);
    5367}
    5468
  • uspace/lib/c/generic/malloc.c

    r8d308b9 r9d47440  
    6565#define BASE_ALIGN  16
    6666
     67/** Heap shrink granularity
     68 *
     69 * Try not to pump and stress the heap to much
     70 * by shrinking and enlarging it too often.
     71 * A heap area won't shrunk if it the released
     72 * free block is smaller than this constant.
     73 *
     74 */
     75#define SHRINK_GRANULARITY  (64 * PAGE_SIZE)
     76
    6777/** Overhead of each heap block. */
    6878#define STRUCT_OVERHEAD \
     
    8696 *
    8797 */
    88 #define AREA_FIRST_BLOCK(area) \
     98#define AREA_FIRST_BLOCK_HEAD(area) \
    8999        (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
     100
     101/** Get last block in heap area.
     102 *
     103 */
     104#define AREA_LAST_BLOCK_FOOT(area) \
     105        (((uintptr_t) (area)->end) - sizeof(heap_block_foot_t))
     106
     107/** Get header in heap block.
     108 *
     109 */
     110#define BLOCK_HEAD(foot) \
     111        ((heap_block_head_t *) \
     112            (((uintptr_t) (foot)) + sizeof(heap_block_foot_t) - (foot)->size))
    90113
    91114/** Get footer in heap block.
     
    94117#define BLOCK_FOOT(head) \
    95118        ((heap_block_foot_t *) \
    96             (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
     119            (((uintptr_t) (head)) + (head)->size - sizeof(heap_block_foot_t)))
    97120
    98121/** Heap area.
     
    115138        void *end;
    116139       
     140        /** Previous heap area */
     141        struct heap_area *prev;
     142       
    117143        /** Next heap area */
    118144        struct heap_area *next;
     
    161187/** Futex for thread-safe heap manipulation */
    162188static futex_t malloc_futex = FUTEX_INITIALIZER;
     189
     190#ifndef NDEBUG
     191
     192#define malloc_assert(expr) \
     193        do { \
     194                if (!(expr)) {\
     195                        futex_up(&malloc_futex); \
     196                        assert_abort(#expr, __FILE__, STR2(__LINE__)); \
     197                } \
     198        } while (0)
     199
     200#else /* NDEBUG */
     201
     202#define malloc_assert(expr)
     203
     204#endif /* NDEBUG */
    163205
    164206/** Initialize a heap block
     
    202244        heap_block_head_t *head = (heap_block_head_t *) addr;
    203245       
    204         assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
     246        malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    205247       
    206248        heap_block_foot_t *foot = BLOCK_FOOT(head);
    207249       
    208         assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
    209         assert(head->size == foot->size);
     250        malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     251        malloc_assert(head->size == foot->size);
    210252}
    211253
    212254/** Check a heap area structure
    213255 *
     256 * Should be called only inside the critical section.
     257 *
    214258 * @param addr Address of the heap area.
    215259 *
     
    219263        heap_area_t *area = (heap_area_t *) addr;
    220264       
    221         assert(area->magic == HEAP_AREA_MAGIC);
    222         assert(area->start < area->end);
    223         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    224         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     265        malloc_assert(area->magic == HEAP_AREA_MAGIC);
     266        malloc_assert(addr == area->start);
     267        malloc_assert(area->start < area->end);
     268        malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     269        malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    225270}
    226271
    227272/** Create new heap area
    228273 *
    229  * @param start Preffered starting address of the new area.
    230  * @param size  Size of the area.
     274 * Should be called only inside the critical section.
     275 *
     276 * @param size Size of the area.
    231277 *
    232278 */
     
    248294       
    249295        area->start = astart;
    250         area->end = (void *)
    251             ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
     296        area->end = (void *) ((uintptr_t) astart + asize);
     297        area->prev = NULL;
    252298        area->next = NULL;
    253299        area->magic = HEAP_AREA_MAGIC;
    254300       
    255         void *block = (void *) AREA_FIRST_BLOCK(area);
     301        void *block = (void *) AREA_FIRST_BLOCK_HEAD(area);
    256302        size_t bsize = (size_t) (area->end - block);
    257303       
     
    262308                last_heap_area = area;
    263309        } else {
     310                area->prev = last_heap_area;
    264311                last_heap_area->next = area;
    265312                last_heap_area = area;
     
    271318/** Try to enlarge a heap area
    272319 *
     320 * Should be called only inside the critical section.
     321 *
    273322 * @param area Heap area to grow.
    274  * @param size Gross size of item to allocate (bytes).
     323 * @param size Gross size to grow (bytes).
     324 *
     325 * @return True if successful.
    275326 *
    276327 */
     
    282333        area_check(area);
    283334       
    284         size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
    285             PAGE_SIZE);
    286        
    287335        /* New heap area size */
    288         void *end = (void *)
    289             ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
     336        size_t gross_size = (size_t) (area->end - area->start) + size;
     337        size_t asize = ALIGN_UP(gross_size, PAGE_SIZE);
     338        void *end = (void *) ((uintptr_t) area->start + asize);
    290339       
    291340        /* Check for overflow */
     
    299348       
    300349        /* Add new free block */
    301         block_init(area->end, (size_t) (end - area->end), true, area);
     350        size_t net_size = (size_t) (end - area->end);
     351        if (net_size > 0)
     352                block_init(area->end, net_size, true, area);
    302353       
    303354        /* Update heap area parameters */
     
    309360/** Try to enlarge any of the heap areas
    310361 *
     362 * Should be called only inside the critical section.
     363 *
    311364 * @param size Gross size of item to allocate (bytes).
    312365 *
     
    318371       
    319372        /* First try to enlarge some existing area */
    320         heap_area_t *area;
    321         for (area = first_heap_area; area != NULL; area = area->next) {
     373        for (heap_area_t *area = first_heap_area; area != NULL;
     374            area = area->next) {
    322375                if (area_grow(area, size))
    323376                        return true;
     
    325378       
    326379        /* Eventually try to create a new area */
    327         return area_create(AREA_FIRST_BLOCK(size));
    328 }
    329 
    330 /** Try to shrink heap space
    331  *
     380        return area_create(AREA_FIRST_BLOCK_HEAD(size));
     381}
     382
     383/** Try to shrink heap
     384 *
     385 * Should be called only inside the critical section.
    332386 * In all cases the next pointer is reset.
    333387 *
    334  */
    335 static void heap_shrink(void)
    336 {
     388 * @param area Last modified heap area.
     389 *
     390 */
     391static void heap_shrink(heap_area_t *area)
     392{
     393        area_check(area);
     394       
     395        heap_block_foot_t *last_foot =
     396            (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area);
     397        heap_block_head_t *last_head = BLOCK_HEAD(last_foot);
     398       
     399        block_check((void *) last_head);
     400        malloc_assert(last_head->area == area);
     401       
     402        if (last_head->free) {
     403                /*
     404                 * The last block of the heap area is
     405                 * unused. The area might be potentially
     406                 * shrunk.
     407                 */
     408               
     409                heap_block_head_t *first_head =
     410                    (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area);
     411               
     412                block_check((void *) first_head);
     413                malloc_assert(first_head->area == area);
     414               
     415                size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
     416               
     417                if (first_head == last_head) {
     418                        /*
     419                         * The entire heap area consists of a single
     420                         * free heap block. This means we can get rid
     421                         * of it entirely.
     422                         */
     423                       
     424                        heap_area_t *prev = area->prev;
     425                        heap_area_t *next = area->next;
     426                       
     427                        if (prev != NULL) {
     428                                area_check(prev);
     429                                prev->next = next;
     430                        } else
     431                                first_heap_area = next;
     432                       
     433                        if (next != NULL) {
     434                                area_check(next);
     435                                next->prev = prev;
     436                        } else
     437                                last_heap_area = prev;
     438                       
     439                        as_area_destroy(area->start);
     440                } else if (shrink_size >= SHRINK_GRANULARITY) {
     441                        /*
     442                         * Make sure that we always shrink the area
     443                         * by a multiple of page size and update
     444                         * the block layout accordingly.
     445                         */
     446                       
     447                        size_t asize = (size_t) (area->end - area->start) - shrink_size;
     448                        void *end = (void *) ((uintptr_t) area->start + asize);
     449                       
     450                        /* Resize the address space area */
     451                        int ret = as_area_resize(area->start, asize, 0);
     452                        if (ret != EOK)
     453                                abort();
     454                       
     455                        /* Update heap area parameters */
     456                        area->end = end;
     457                       
     458                        /* Update block layout */
     459                        void *last = (void *) last_head;
     460                        size_t excess = (size_t) (area->end - last);
     461                       
     462                        if (excess > 0) {
     463                                if (excess >= STRUCT_OVERHEAD) {
     464                                        /*
     465                                         * The previous block cannot be free and there
     466                                         * is enough free space left in the area to
     467                                         * create a new free block.
     468                                         */
     469                                        block_init(last, excess, true, area);
     470                                } else {
     471                                        /*
     472                                         * The excess is small. Therefore just enlarge
     473                                         * the previous block.
     474                                         */
     475                                        heap_block_foot_t *prev_foot = (heap_block_foot_t *)
     476                                            (((uintptr_t) last_head) - sizeof(heap_block_foot_t));
     477                                        heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot);
     478                                       
     479                                        block_check((void *) prev_head);
     480                                       
     481                                        block_init(prev_head, prev_head->size + excess,
     482                                            prev_head->free, area);
     483                                }
     484                        }
     485                }
     486        }
     487       
    337488        next = NULL;
    338489}
     
    362513static void split_mark(heap_block_head_t *cur, const size_t size)
    363514{
    364         assert(cur->size >= size);
     515        malloc_assert(cur->size >= size);
    365516       
    366517        /* See if we should split the block. */
     
    398549{
    399550        area_check((void *) area);
    400         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
    401         assert((void *) first_block < area->end);
    402        
    403         heap_block_head_t *cur;
    404         for (cur = first_block; (void *) cur < area->end;
     551        malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     552        malloc_assert((void *) first_block < area->end);
     553       
     554        for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
    405555            cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
    406556                block_check(cur);
     
    436586                                         * data in (including alignment).
    437587                                         */
    438                                         if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
     588                                        if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    439589                                                /*
    440590                                                 * There is a block before the current block.
     
    496646                                                        size_t reduced_size = cur->size - excess;
    497647                                                        cur = (heap_block_head_t *)
    498                                                             (AREA_FIRST_BLOCK(area) + excess);
     648                                                            (AREA_FIRST_BLOCK_HEAD(area) + excess);
    499649                                                       
    500                                                         block_init((void *) AREA_FIRST_BLOCK(area), excess,
    501                                                             true, area);
     650                                                        block_init((void *) AREA_FIRST_BLOCK_HEAD(area),
     651                                                            excess, true, area);
    502652                                                        block_init(cur, reduced_size, true, area);
    503653                                                        split_mark(cur, real_size);
     
    527677static void *malloc_internal(const size_t size, const size_t align)
    528678{
    529         assert(first_heap_area != NULL);
     679        malloc_assert(first_heap_area != NULL);
    530680       
    531681        if (align == 0)
     
    552702       
    553703        /* Search the entire heap */
    554         heap_area_t *area;
    555         for (area = first_heap_area; area != NULL; area = area->next) {
     704        for (heap_area_t *area = first_heap_area; area != NULL;
     705            area = area->next) {
    556706                heap_block_head_t *first = (heap_block_head_t *)
    557                     AREA_FIRST_BLOCK(area);
     707                    AREA_FIRST_BLOCK_HEAD(area);
    558708               
    559709                void *addr = malloc_area(area, first, split, real_size,
     
    652802       
    653803        block_check(head);
    654         assert(!head->free);
     804        malloc_assert(!head->free);
    655805       
    656806        heap_area_t *area = head->area;
    657807       
    658808        area_check(area);
    659         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    660         assert((void *) head < area->end);
     809        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     810        malloc_assert((void *) head < area->end);
    661811       
    662812        void *ptr = NULL;
     
    675825                        block_init((void *) head + real_size,
    676826                            orig_size - real_size, true, area);
    677                         heap_shrink();
     827                        heap_shrink(area);
    678828                }
    679829               
     
    729879       
    730880        block_check(head);
    731         assert(!head->free);
     881        malloc_assert(!head->free);
    732882       
    733883        heap_area_t *area = head->area;
    734884       
    735885        area_check(area);
    736         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    737         assert((void *) head < area->end);
     886        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     887        malloc_assert((void *) head < area->end);
    738888       
    739889        /* Mark the block itself as free. */
     
    751901       
    752902        /* Look at the previous block. If it is free, merge the two. */
    753         if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
     903        if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    754904                heap_block_foot_t *prev_foot =
    755905                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    765915        }
    766916       
    767         heap_shrink();
     917        heap_shrink(area);
    768918       
    769919        futex_up(&malloc_futex);
    770920}
    771921
     922void *heap_check(void)
     923{
     924        futex_down(&malloc_futex);
     925       
     926        if (first_heap_area == NULL) {
     927                futex_up(&malloc_futex);
     928                return (void *) -1;
     929        }
     930       
     931        /* Walk all heap areas */
     932        for (heap_area_t *area = first_heap_area; area != NULL;
     933            area = area->next) {
     934               
     935                /* Check heap area consistency */
     936                if ((area->magic != HEAP_AREA_MAGIC) ||
     937                    ((void *) area != area->start) ||
     938                    (area->start >= area->end) ||
     939                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
     940                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
     941                        futex_up(&malloc_futex);
     942                        return (void *) area;
     943                }
     944               
     945                /* Walk all heap blocks */
     946                for (heap_block_head_t *head = (heap_block_head_t *)
     947                    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
     948                    head = (heap_block_head_t *) (((void *) head) + head->size)) {
     949                       
     950                        /* Check heap block consistency */
     951                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
     952                                futex_up(&malloc_futex);
     953                                return (void *) head;
     954                        }
     955                       
     956                        heap_block_foot_t *foot = BLOCK_FOOT(head);
     957                       
     958                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
     959                            (head->size != foot->size)) {
     960                                futex_up(&malloc_futex);
     961                                return (void *) foot;
     962                        }
     963                }
     964        }
     965       
     966        futex_up(&malloc_futex);
     967       
     968        return NULL;
     969}
     970
    772971/** @}
    773972 */
  • uspace/lib/c/include/adt/list.h

    r8d308b9 r9d47440  
    4949 *
    5050 */
    51 #define LIST_INITIALIZE(name)  link_t name = { \
    52         .prev = &name, \
    53         .next = &name \
    54 }
     51#define LIST_INITIALIZE(name) \
     52        link_t name = { \
     53                .prev = &name, \
     54                .next = &name \
     55        }
     56
     57#define list_get_instance(link, type, member) \
     58        ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
     59
     60#define list_foreach(list, iterator) \
     61        for (link_t *iterator = (list).next; \
     62            iterator != &(list); iterator = iterator->next)
    5563
    5664/** Initialize doubly-linked circular list link
     
    7179 * Initialize doubly-linked circular list.
    7280 *
    73  * @param head Pointer to link_t structure representing head of the list.
    74  *
    75  */
    76 static inline void list_initialize(link_t *head)
    77 {
    78         head->prev = head;
    79         head->next = head;
     81 * @param list Pointer to link_t structure representing the list.
     82 *
     83 */
     84static inline void list_initialize(link_t *list)
     85{
     86        list->prev = list;
     87        list->next = list;
    8088}
    8189
     
    8593 *
    8694 * @param link Pointer to link_t structure to be added.
    87  * @param head Pointer to link_t structure representing head of the list.
    88  *
    89  */
    90 static inline void list_prepend(link_t *link, link_t *head)
    91 {
    92         link->next = head->next;
    93         link->prev = head;
    94         head->next->prev = link;
    95         head->next = link;
     95 * @param list Pointer to link_t structure representing the list.
     96 *
     97 */
     98static inline void list_prepend(link_t *link, link_t *list)
     99{
     100        link->next = list->next;
     101        link->prev = list;
     102        list->next->prev = link;
     103        list->next = link;
    96104}
    97105
     
    101109 *
    102110 * @param link Pointer to link_t structure to be added.
    103  * @param head Pointer to link_t structure representing head of the list.
    104  *
    105  */
    106 static inline void list_append(link_t *link, link_t *head)
    107 {
    108         link->prev = head->prev;
    109         link->next = head;
    110         head->prev->next = link;
    111         head->prev = link;
    112 }
    113 
    114 /** Insert item before another item in doubly-linked circular list. */
    115 static inline void list_insert_before(link_t *l, link_t *r)
    116 {
    117         list_append(l, r);
    118 }
    119 
    120 /** Insert item after another item in doubly-linked circular list. */
    121 static inline void list_insert_after(link_t *r, link_t *l)
    122 {
    123         list_prepend(l, r);
     111 * @param list Pointer to link_t structure representing the list.
     112 *
     113 */
     114static inline void list_append(link_t *link, link_t *list)
     115{
     116        link->prev = list->prev;
     117        link->next = list;
     118        list->prev->next = link;
     119        list->prev = link;
     120}
     121
     122/** Insert item before another item in doubly-linked circular list.
     123 *
     124 */
     125static inline void list_insert_before(link_t *link, link_t *list)
     126{
     127        list_append(link, list);
     128}
     129
     130/** Insert item after another item in doubly-linked circular list.
     131 *
     132 */
     133static inline void list_insert_after(link_t *link, link_t *list)
     134{
     135        list_prepend(list, link);
    124136}
    125137
     
    143155 * Query emptiness of doubly-linked circular list.
    144156 *
    145  * @param head Pointer to link_t structure representing head of the list.
    146  *
    147  */
    148 static inline int list_empty(link_t *head)
    149 {
    150         return ((head->next == head) ? 1 : 0);
     157 * @param list Pointer to link_t structure representing the list.
     158 *
     159 */
     160static inline int list_empty(link_t *list)
     161{
     162        return (list->next == list);
     163}
     164
     165/** Get head item of a list.
     166 *
     167 * @param list Pointer to link_t structure representing the list.
     168 *
     169 * @return Head item of the list.
     170 * @return NULL if the list is empty.
     171 *
     172 */
     173static inline link_t *list_head(link_t *list)
     174{
     175        return ((list->next == list) ? NULL : list->next);
    151176}
    152177
     
    205230}
    206231
    207 #define list_get_instance(link, type, member) \
    208         ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
    209 
    210 #define list_foreach(list, iterator) \
    211         for (link_t *iterator = (list).next; \
    212             iterator != &(list); iterator = iterator->next)
     232/** Get n-th item of a list.
     233 *
     234 * @param list Pointer to link_t structure representing the list.
     235 * @param n    Item number (indexed from zero).
     236 *
     237 * @return n-th item of the list.
     238 * @return NULL if no n-th item found.
     239 *
     240 */
     241static inline link_t *list_nth(link_t *list, unsigned int n)
     242{
     243        unsigned int cnt = 0;
     244       
     245        list_foreach(*list, link) {
     246                if (cnt == n)
     247                        return link;
     248               
     249                cnt++;
     250        }
     251       
     252        return NULL;
     253}
    213254
    214255extern int list_member(const link_t *, const link_t *);
  • uspace/lib/c/include/as.h

    r8d308b9 r9d47440  
    5959extern int as_area_destroy(void *);
    6060extern void *set_maxheapsize(size_t);
    61 extern void * as_get_mappable_page(size_t);
     61extern void *as_get_mappable_page(size_t);
    6262
    6363#endif
  • uspace/lib/c/include/assert.h

    r8d308b9 r9d47440  
    4747 */
    4848
     49#define STR(l)  #l
     50#define STR2(l) STR(l)
     51
    4952#ifndef NDEBUG
    5053
     
    5255        do { \
    5356                if (!(expr)) \
    54                         assert_abort(#expr, __FILE__, __LINE__); \
     57                        assert_abort(#expr, __FILE__, STR2(__LINE__)); \
    5558        } while (0)
    5659
     
    6164#endif /* NDEBUG */
    6265
    63 extern void assert_abort(const char *, const char *, unsigned int)
     66extern void assert_abort(const char *, const char *, const char *)
    6467    __attribute__((noreturn));
     68
    6569
    6670#endif
  • uspace/lib/c/include/event.h

    r8d308b9 r9d47440  
    3939
    4040extern int event_subscribe(event_type_t, sysarg_t);
     41extern int event_unmask(event_type_t);
    4142
    4243#endif
  • uspace/lib/c/include/malloc.h

    r8d308b9 r9d47440  
    4646extern void *realloc(const void *addr, const size_t size);
    4747extern void free(const void *addr);
     48extern void *heap_check(void);
    4849
    4950#endif
Note: See TracChangeset for help on using the changeset viewer.