static thread_data_t* _log_create_thread_data() { thread_data_t* th_data = calloc(1, sizeof (thread_data_t)); fmbuf* pbuf = fmbuf_create(g_log->buffer_size); if ( !pbuf ) { printError("cannot alloc memory for thread data"); _destroy_thread_data(th_data); return NULL; } th_data->plog_buf = pbuf; // for forward compatible old version of kernel from 2.6.22 - 2.6.26 // we couldn't use EFD_NONBLOCK flag, so we need to call fcntl for // setting nonblocking flag int efd = eventfd(0, 0); if (!efd) { printError("error in creating efd"); _destroy_thread_data(th_data); return NULL; } if ( _log_set_nonblocking(efd) == -1 ) { printError("error in set nonblocking flag for efd"); _destroy_thread_data(th_data); return NULL; } if ( efd == -1 ) { printError("cannot create eventfd for thread data"); _destroy_thread_data(th_data); return NULL; } th_data->efd = efd; struct epoll_event ee; memset(&ee, 0, sizeof(ee)); ee.data.u64 = 0; ee.data.fd = 0; ee.data.ptr = th_data; ee.events = 0; ee.events |= EPOLLIN; if ( epoll_ctl( g_log->epfd, EPOLL_CTL_ADD, efd, &ee) ) { printError("cannot add eventfd into epoll for thread data"); _destroy_thread_data(th_data); return NULL; } th_data->last_time = 0; _log_clear_cookie(th_data); return th_data; }
int fthpool_add_thread(void* pri_arg) { thread_data* th_data = calloc(1, sizeof(thread_data)); th_data->tid = th_id++; th_data->pbuf = fmbuf_create(TH_QUEUE_BUF_SIZE); th_data->parg = pri_arg; flock_cond_init(&th_data->cond); pthread_t t; int rc = pthread_create(&t, 0, base_work, th_data); if ( 0 != rc ) { fmbuf_delete(th_data->pbuf); free(th_data); return -1; } fhash_int_set(g_th_pool, th_data->tid, th_data); pth_pool[curr_num++] = th_data; return th_data->tid; }
// test fmbuf push and pop void test_mbuf1() { // create a mbuf with size == 0 { fmbuf* pbuf = fmbuf_create(0); FCUNIT_ASSERT(pbuf != NULL); FCUNIT_ASSERT(0 == fmbuf_size(pbuf)); FCUNIT_ASSERT(0 == fmbuf_used(pbuf)); FCUNIT_ASSERT(0 == fmbuf_free(pbuf)); fmbuf_delete(pbuf); } fmbuf* pbuf = fmbuf_create(10); FCUNIT_ASSERT(pbuf!=NULL); char* push_buf[20]; char* pop_buf[20]; // push 1 byte data { int ret = fmbuf_push(pbuf, push_buf, 1); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(1 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(9 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(9 == total_free); } // push 9 byte data { int ret = fmbuf_push(pbuf, push_buf, 9); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(0 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(0 == total_free); } // continue push 1 byte data when mbuf is full { int ret = fmbuf_push(pbuf, push_buf, 1); FCUNIT_ASSERT(1 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(0 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(0 == total_free); } // clear and seek mbuf and push 5 bytes { fmbuf_clear(pbuf); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(10 == total_free); fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 6, FMBUF_SEEK_RIGHT); int ret = fmbuf_push(pbuf, push_buf, 5); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(7 == used); total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(3 == total_free); } // push 4 bytes but the mbuf only have 3 bytes left { int ret = fmbuf_push(pbuf, push_buf, 4); FCUNIT_ASSERT(1 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(7 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(3 == total_free); } // push 3 bytes the mbuf is full { int ret = fmbuf_push(pbuf, push_buf, 3); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(0 == total_free); ret = fmbuf_push(pbuf, push_buf, 1); FCUNIT_ASSERT(1 == ret); } //---------------mbuf pop------------------- //pop 1 bytes { fmbuf_clear(pbuf); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); int ret = fmbuf_pop(pbuf, pop_buf, 1); FCUNIT_ASSERT(1 == ret); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(0 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(10 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(10 == total_free); } // push 5 bytes and pop 1 bytes { int ret = fmbuf_push(pbuf, push_buf, 5); FCUNIT_ASSERT(0 == ret); ret = fmbuf_pop(pbuf, pop_buf, 1); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(4 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(1 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(5 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(6 == total_free); } // pop 3 bytes and left 1 byte { int ret = fmbuf_pop(pbuf, pop_buf, 3); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(1 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(4 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(5 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(9 == total_free); } // pop 2 bytes { int ret = fmbuf_pop(pbuf, pop_buf, 2); FCUNIT_ASSERT(1 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(1 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(4 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(5 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(9 == total_free); } // clear mbuf and seek tail < head { fmbuf_clear(pbuf); fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 2, FMBUF_SEEK_RIGHT); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(9 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(4 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(8 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(1 == total_free); } // total 9 bytes, pop 7 bytes { int ret = fmbuf_pop(pbuf, pop_buf, 7); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(2 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(8 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(8 == total_free); } // pop 2 bytes and then the mbuf is empty { int ret = fmbuf_pop(pbuf, pop_buf, 2); FCUNIT_ASSERT(0 == ret); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(0 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(2 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(8 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(10 == total_free); } { fmbuf_clear(pbuf); fmbuf_head_seek(pbuf, 4, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 6, FMBUF_SEEK_RIGHT); int ret = fmbuf_pop(pbuf, NULL, 4); FCUNIT_ASSERT(ret == 1); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(2 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(4 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(4 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(8 == total_free); } // move 2 bytes { fmbuf_pop(pbuf, NULL, 2); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(0 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(6 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(4 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(10 == total_free); } // tail < head, tail_use == 5, but pop 6 bytes { fmbuf_clear(pbuf); fmbuf_head_seek(pbuf, 6, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 4, FMBUF_SEEK_RIGHT); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(9 == used); fmbuf_pop(pbuf, NULL, 6); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); used = fmbuf_used(pbuf); FCUNIT_ASSERT(3 == used); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(1 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(6 == tail_free); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(7 == total_free); } fmbuf_delete(pbuf); }
// test fmbuf(array) seek/rewind/realloc void test_mbuf() { fmbuf* pbuf = fmbuf_create(100); { size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(0 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(100 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(100 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(100 == size); } // setup mbuf, header at 10, tailer at 20 (10 bytes used) { fmbuf_head_seek(pbuf, 10, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 20, FMBUF_SEEK_RIGHT); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(90 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(10 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(80 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(100 == size); } // rewind it { fmbuf_rewind(pbuf); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(90 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(90 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(100 == size); } // realloc it with same size { fmbuf* new_buf = fmbuf_realloc(pbuf, 100); FCUNIT_ASSERT((new_buf==pbuf)); } // increase the mbuf size { fmbuf* new_buf = pbuf; pbuf = fmbuf_realloc(new_buf, 200); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(190 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(190 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(200 == size); } // decrease the buff size < data size { pbuf = fmbuf_realloc(pbuf, 5); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(0 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(0 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(10 == size); } // realloc it, new buffer size > data size { pbuf = fmbuf_realloc(pbuf, 100); fmbuf_head_seek(pbuf, 10, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(pbuf, 10, FMBUF_SEEK_RIGHT); pbuf = fmbuf_realloc(pbuf, 15); size_t used = fmbuf_used(pbuf); FCUNIT_ASSERT(10 == used); size_t total_free = fmbuf_free(pbuf); FCUNIT_ASSERT(5 == total_free); size_t head_free = fmbuf_head_free(pbuf); FCUNIT_ASSERT(0 == head_free); size_t tail_free = fmbuf_tail_free(pbuf); FCUNIT_ASSERT(5 == tail_free); size_t size = fmbuf_size(pbuf); FCUNIT_ASSERT(15 == size); } fmbuf_delete(pbuf); }
// mbuf as a ring-buffer (the tailer location < header location) void test_mbuf2() { // mbuf: size = 10b, used = 2b // realloc it with same size { fmbuf* mbuf = fmbuf_create(10); int ret = fmbuf_push(mbuf, "11", 2); FCUNIT_ASSERT(ret == 0); fmbuf* new_buf = fmbuf_realloc(mbuf, 10); FCUNIT_ASSERT(new_buf == mbuf); fmbuf_delete(mbuf); } // mbuf: size = 10b, used = 9b // realloc it with new size = 20b // note: left used <= right used and left used <= increased sz { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 4, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 2, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 9); fmbuf* new_buf = fmbuf_realloc(mbuf, 20); FCUNIT_ASSERT(9 == fmbuf_used(new_buf)); FCUNIT_ASSERT(11 == fmbuf_free(new_buf)); FCUNIT_ASSERT(20 == fmbuf_size(new_buf)); FCUNIT_ASSERT(4 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(7 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } // mbuf: size = 10b, used = 9b // realloc it with new size = 20b // note: left used > right used, left used <= increased sz { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 8, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 6, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 9); fmbuf* new_buf = fmbuf_realloc(mbuf, 20); FCUNIT_ASSERT(9 == fmbuf_used(new_buf)); FCUNIT_ASSERT(11 == fmbuf_free(new_buf)); FCUNIT_ASSERT(20 == fmbuf_size(new_buf)); FCUNIT_ASSERT(18 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(14 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } // mbuf: size = 10b, used = 9b // realloc it with new size = 11b // note: left used <= right used, left used > increased sz { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 4, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 2, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 9); fmbuf* new_buf = fmbuf_realloc(mbuf, 11); FCUNIT_ASSERT(9 == fmbuf_used(new_buf)); FCUNIT_ASSERT(2 == fmbuf_free(new_buf)); FCUNIT_ASSERT(11 == fmbuf_size(new_buf)); FCUNIT_ASSERT(5 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(9 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } // mbuf: size = 10b, used = 9b // realloc it with new size = 11b // note: left used > right used, left used > increased sz { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 8, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 6, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 9); fmbuf* new_buf = fmbuf_realloc(mbuf, 11); FCUNIT_ASSERT(9 == fmbuf_used(new_buf)); FCUNIT_ASSERT(2 == fmbuf_free(new_buf)); FCUNIT_ASSERT(11 == fmbuf_size(new_buf)); FCUNIT_ASSERT(9 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(5 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } // mbuf: size = 10b, used = 2b // realloc it with new size = 5b { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 10, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 1, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 2); fmbuf* new_buf = fmbuf_realloc(mbuf, 5); FCUNIT_ASSERT(2 == fmbuf_used(new_buf)); FCUNIT_ASSERT(3 == fmbuf_free(new_buf)); FCUNIT_ASSERT(5 == fmbuf_size(new_buf)); FCUNIT_ASSERT(5 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(4 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } // mbuf: size = 10b, used = 2b // realloc it with new size = 1b { fmbuf* mbuf = fmbuf_create(10); fmbuf_head_seek(mbuf, 10, FMBUF_SEEK_RIGHT); fmbuf_tail_seek(mbuf, 1, FMBUF_SEEK_RIGHT); FCUNIT_ASSERT(fmbuf_used(mbuf) == 2); fmbuf* new_buf = fmbuf_realloc(mbuf, 1); FCUNIT_ASSERT(2 == fmbuf_used(new_buf)); FCUNIT_ASSERT(0 == fmbuf_free(new_buf)); FCUNIT_ASSERT(2 == fmbuf_size(new_buf)); FCUNIT_ASSERT(2 == fmbuf_head_free(new_buf)); FCUNIT_ASSERT(1 == fmbuf_tail_free(new_buf)); fmbuf_delete(new_buf); } }