10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 30Sigor@sysoev.ru * Copyright (C) Igor Sysoev 40Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 50Sigor@sysoev.ru */ 60Sigor@sysoev.ru 70Sigor@sysoev.ru #include <nxt_main.h> 80Sigor@sysoev.ru 90Sigor@sysoev.ru 100Sigor@sysoev.ru nxt_list_t * 1165Sigor@sysoev.ru nxt_list_create(nxt_mp_t *mp, nxt_uint_t n, size_t size) 120Sigor@sysoev.ru { 130Sigor@sysoev.ru nxt_list_t *list; 140Sigor@sysoev.ru 1565Sigor@sysoev.ru list = nxt_mp_get(mp, sizeof(nxt_list_t) + n * size); 160Sigor@sysoev.ru 170Sigor@sysoev.ru if (nxt_fast_path(list != NULL)) { 180Sigor@sysoev.ru list->last = &list->part; 190Sigor@sysoev.ru list->size = size; 200Sigor@sysoev.ru list->nalloc = n; 210Sigor@sysoev.ru list->mem_pool = mp; 220Sigor@sysoev.ru list->part.next = NULL; 230Sigor@sysoev.ru list->part.nelts = 0; 240Sigor@sysoev.ru } 250Sigor@sysoev.ru 260Sigor@sysoev.ru return list; 270Sigor@sysoev.ru } 280Sigor@sysoev.ru 290Sigor@sysoev.ru 300Sigor@sysoev.ru void * 310Sigor@sysoev.ru nxt_list_add(nxt_list_t *list) 320Sigor@sysoev.ru { 330Sigor@sysoev.ru void *elt; 340Sigor@sysoev.ru nxt_list_part_t *last; 350Sigor@sysoev.ru 360Sigor@sysoev.ru last = list->last; 370Sigor@sysoev.ru 380Sigor@sysoev.ru if (last->nelts == list->nalloc) { 390Sigor@sysoev.ru 400Sigor@sysoev.ru /* The last list part is filled up, allocating a new list part. */ 410Sigor@sysoev.ru 4265Sigor@sysoev.ru last = nxt_mp_get(list->mem_pool, 4365Sigor@sysoev.ru sizeof(nxt_list_part_t) + list->nalloc * list->size); 440Sigor@sysoev.ru 450Sigor@sysoev.ru if (nxt_slow_path(last == NULL)) { 460Sigor@sysoev.ru return NULL; 470Sigor@sysoev.ru } 480Sigor@sysoev.ru 490Sigor@sysoev.ru last->next = NULL; 500Sigor@sysoev.ru last->nelts = 0; 510Sigor@sysoev.ru 520Sigor@sysoev.ru list->last->next = last; 530Sigor@sysoev.ru list->last = last; 540Sigor@sysoev.ru } 550Sigor@sysoev.ru 56*108Sigor@sysoev.ru elt = nxt_pointer_to(nxt_list_data(last), last->nelts * list->size); 570Sigor@sysoev.ru last->nelts++; 580Sigor@sysoev.ru 590Sigor@sysoev.ru return elt; 600Sigor@sysoev.ru } 610Sigor@sysoev.ru 620Sigor@sysoev.ru 630Sigor@sysoev.ru void * 640Sigor@sysoev.ru nxt_list_zero_add(nxt_list_t *list) 650Sigor@sysoev.ru { 660Sigor@sysoev.ru void *p; 670Sigor@sysoev.ru 680Sigor@sysoev.ru p = nxt_list_add(list); 690Sigor@sysoev.ru 700Sigor@sysoev.ru if (nxt_fast_path(p != NULL)) { 710Sigor@sysoev.ru nxt_memzero(p, list->size); 720Sigor@sysoev.ru } 730Sigor@sysoev.ru 740Sigor@sysoev.ru return p; 750Sigor@sysoev.ru } 760Sigor@sysoev.ru 770Sigor@sysoev.ru 780Sigor@sysoev.ru void * 790Sigor@sysoev.ru nxt_list_next(nxt_list_t *list, nxt_list_next_t *next) 800Sigor@sysoev.ru { 810Sigor@sysoev.ru if (next->part != NULL) { 820Sigor@sysoev.ru next->elt++; 830Sigor@sysoev.ru 840Sigor@sysoev.ru if (next->elt < next->part->nelts) { 850Sigor@sysoev.ru return nxt_list_next_value(list, next); 860Sigor@sysoev.ru } 870Sigor@sysoev.ru 880Sigor@sysoev.ru next->part = next->part->next; 890Sigor@sysoev.ru 900Sigor@sysoev.ru if (next->part != NULL) { 910Sigor@sysoev.ru next->elt = 0; 920Sigor@sysoev.ru return nxt_list_data(next->part); 930Sigor@sysoev.ru } 940Sigor@sysoev.ru 950Sigor@sysoev.ru } else { 960Sigor@sysoev.ru next->part = nxt_list_part(list); 970Sigor@sysoev.ru /* 980Sigor@sysoev.ru * The first list part is allocated together with 990Sigor@sysoev.ru * a nxt_list_t itself and it may never be NULL. 1000Sigor@sysoev.ru */ 1010Sigor@sysoev.ru if (next->part->nelts != 0) { 1020Sigor@sysoev.ru return nxt_list_data(next->part); 1030Sigor@sysoev.ru } 1040Sigor@sysoev.ru 1050Sigor@sysoev.ru } 1060Sigor@sysoev.ru 1070Sigor@sysoev.ru return NULL; 1080Sigor@sysoev.ru } 109