示例#1
0
文件: test.c 项目: Walkerks/locks
static void test_condition_variables (void)
{
  thrd_t t1, t[40];
  int i;

  /* Set the global counter to the number of threads to run. */
  gCount = 40;

  /* Start the waiting thread (it will wait for gCount to reach
     zero). */
  thrd_create(&t1, thread_condition_waiter, NULL);

  /* Start a bunch of child threads (these will decrease gCount by 1
     when they finish) */
  for (i = 0; i < 40; ++ i)
  {
    thrd_create(&t[i], thread_condition_notifier, NULL);
  }

  /* Wait for the waiting thread to finish */
  thrd_join(t1, NULL);

  /* Wait for the other threads to finish */
  for (i = 0; i < 40; ++ i)
  {
    thrd_join(t[i], NULL);
  }
}
int main(void)
{
    if (mtx_init(&mtx, mtx_plain) != thrd_success)
    {
        fprintf(stderr, "Error initializing the mutex.\n");
        return -1;
    }

    // As in Example 14-2: 
    // start threads, wait for them to finish, print output:
    clock_t cl = clock();
    thrd_t th1, th2;

    if( thrd_create(&th1, (thrd_start_t)incFunc, NULL) != thrd_success
        || thrd_create(&th2, (thrd_start_t)decFunc, NULL) != thrd_success)
    {
        fprintf(stderr,"Error creating thread\n"); return -1;
    }
    thrd_join(th1, NULL);
    thrd_join(th2, NULL);

    printf("Counter: %ld \t", counter);
    printf("CPU time: %ld ms\n", (clock()-cl)*1000L/CLOCKS_PER_SEC);

    mtx_destroy(&mtx);
    return 0;
}
static void b1(void *obj)
{
	thrd_t t3, t4;
	int i = 7;
	int r = atomic_load_explicit(&x, memory_order_acquire);
	printf("r = %d\n", r);
	store_32(&var, 2);
	thrd_create(&t3, (thrd_start_t)&a, &i);
	thrd_create(&t4, (thrd_start_t)&b2, NULL);
	thrd_join(t3);
	thrd_join(t4);
}
示例#4
0
static zx_status_t bio_random(bio_random_args_t* a, uint64_t* _total, zx_duration_t* _res) {

    thrd_t t;
    int r;

    size_t count = a->count;
    zx_handle_t fifo = a->blk->fifo;

    zx_time_t t0 = zx_clock_get_monotonic();
    thrd_create(&t, bio_random_thread, a);

    while (count > 0) {
        block_fifo_response_t resp;
        zx_status_t r = zx_fifo_read(fifo, sizeof(resp), &resp, 1, NULL);
        if (r == ZX_ERR_SHOULD_WAIT) {
            r = zx_object_wait_one(fifo, ZX_FIFO_READABLE | ZX_FIFO_PEER_CLOSED,
                                   ZX_TIME_INFINITE, NULL);
            if (r != ZX_OK) {
                fprintf(stderr, "failed waiting for fifo: %d\n", r);
                goto fail;
            }
            continue;
        } else if (r < 0) {
            fprintf(stderr, "error: failed reading fifo: %d\n", r);
            goto fail;
        }
        if (resp.status != ZX_OK) {
            fprintf(stderr, "error: io txn failed %d (%zu remaining)\n",
                    resp.status, count);
            goto fail;
        }
        count--;
        if (a->pending.fetch_sub(1) == a->max_pending) {
            sync_completion_signal(&a->signal);
        }
    }

    zx_time_t t1;
    t1 = zx_clock_get_monotonic();

    fprintf(stderr, "waiting for thread to exit...\n");
    thrd_join(t, &r);

    *_res = zx_time_sub_time(t1, t0);
    *_total = a->count * a->xfer;
    return ZX_OK;

fail:
    zx_handle_close(a->blk->fifo);
    thrd_join(t, &r);
    return ZX_ERR_IO;
}
int user_main(int argc, char **argv)
{
	thrd_t t1, t2;
	atomic_init(&mylock.lock, RW_LOCK_BIAS);

	thrd_create(&t1, (thrd_start_t)&a, NULL);
	thrd_create(&t2, (thrd_start_t)&a, NULL);

	thrd_join(t1);
	thrd_join(t2);

	return 0;
}
示例#6
0
static int
do_test (void)
{
  /* Setting an invalid key should return an error.  */
  if (tss_set (key, TSS_VALUE) == thrd_success)
    FAIL_EXIT1 ("tss_set succeed where it should have failed");

  if (tss_create (&key, NULL) != thrd_success)
    FAIL_EXIT1 ("tss_create failed");

  thrd_t id;
  if (thrd_create (&id, tss_thrd, NULL) != thrd_success)
    FAIL_EXIT1 ("thrd_create failed");

  if (thrd_join (id, NULL) != thrd_success)
    FAIL_EXIT1 ("thrd failed");

  /* The value set in tss_thrd should not be visible here.  */
  void *value = tss_get (key);
  if (value != 0)
    FAIL_EXIT1 ("tss_get succeed where it should have failed");

  tss_delete (key);

  return 0;
}
示例#7
0
bool thread_action_test(thrd_cb_t cb, void* arg = nullptr) {
    BEGIN_HELPER;

    static_assert(kNumThreads >= kSuccessCount, "Need more threads or less successes");

    thrd_t threads[kNumThreads];
    for (size_t i = 0; i < kNumThreads; i++) {
        ASSERT_EQ(thrd_create(&threads[i], cb, arg), thrd_success);
    }

    size_t success_count = 0;
    for (size_t i = 0; i < kNumThreads; i++) {
        int rc;
        ASSERT_EQ(thrd_join(threads[i], &rc), thrd_success);
        if (rc == kSuccess) {
            success_count++;
            ASSERT_LE(success_count, kSuccessCount, "Too many succeeding threads");
        } else {
            ASSERT_EQ(rc, kFailure, "Unexpected return code from worker thread");
        }
    }
    ASSERT_EQ(success_count, kSuccessCount, "Not enough succeeding threads");

    END_HELPER;
}
示例#8
0
文件: test.c 项目: Walkerks/locks
static void test_tss (void)
{
  thrd_t threads[TEST_TSS_N_THREADS];
  int* value = (int*)malloc(sizeof(int));
  int i;

  *value = rand();

  tss_create(&(test_tss_data.key), test_tss_free);
  mtx_init(&(test_tss_data.mutex), mtx_plain);
  test_tss_data.values_freed = 0;

  assert(tss_get(test_tss_data.key) == NULL);
  tss_set(test_tss_data.key, value);
  assert(tss_get(test_tss_data.key) == value);

  for (i = 0; i < TEST_TSS_N_THREADS; i++)
  {
    thrd_create(&(threads[i]), test_tss_thread_func, NULL);
  }

  for (i = 0; i < TEST_TSS_N_THREADS; i++)
  {
    thrd_join(threads[i], NULL);
  }

  assert(test_tss_data.values_freed == TEST_TSS_N_THREADS);
  assert(tss_get(test_tss_data.key) == value);
  tss_delete(test_tss_data.key);
  assert(tss_get(test_tss_data.key) == NULL);
  assert(test_tss_data.values_freed == TEST_TSS_N_THREADS);

  free(value);
}
示例#9
0
文件: test.c 项目: Walkerks/locks
static void test_once (void)
{
  const once_flag once_flag_init = ONCE_FLAG_INIT;
  thrd_t threads[TEST_ONCE_N_THREADS];
  int i;

  /* Initialize 10000 once_flags */
  for (i = 0; i < 10000 ; i++)
  {
    onceFlags[i] = once_flag_init;
  }

  /* Clear the global counter. */
  mtx_lock(&gMutex);
  gCount = 0;
  mtx_unlock(&gMutex);

  /* Create threads */
  for (i = 0; i < TEST_ONCE_N_THREADS; i++)
  {
    thrd_create(&(threads[i]), thread_once, NULL);
  }

  /* Wait for all threads to finish executing. */
  for (i = 0; i < TEST_ONCE_N_THREADS; i++)
  {
    thrd_join(threads[i], NULL);
  }

  /* Check the global count */
  assert(gCount == 10000);
}
示例#10
0
LoadGeneratorThread::~LoadGeneratorThread() {
    if (thread_started_) {
        int musl_ret;
        quit_ = true;
        thrd_join(thread_, &musl_ret);
    }
}
示例#11
0
int main(int argc, char **argv)
{
    thrd_t t[TRDS];
    size_t i;
    struct add a[TRDS];
    size_t gt = 0;
    int ep = 0;

    p = &t[0];

    if( argc != 2 ) {
        puts("An integer argument must be passed");
        exit(1);
    }

    size_t in = (size_t)atoi(argv[1]);

    for(i=0; i<TRDS; i++) {
        a[i].start = i*(in/TRDS) + 1;
        if(i == (TRDS-1)) {
            ep = in - TRDS*(in/TRDS); //In case of odd number, the last thread will do an extra addition
        }
        a[i].end = a[i].start + in/TRDS - 1 + ep;
        thrd_create(&t[i], func, &a[i]);
    }

    for(i=0; i<TRDS; i++) {
        thrd_join(t[i], 0);
        gt += a[i].tot;
    }

    printf("n*(n+1)/2 = %zu Grand Total: %zu \n", in*(in+1)/2, gt);

    return 0;
}
示例#12
0
zx_status_t AmlUart::SerialImplEnable(bool enable) {
    fbl::AutoLock al(&enable_lock_);

    if (enable && !enabled_) {
        zx_status_t status = pdev_map_interrupt(&pdev_, 0, irq_.reset_and_get_address());
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s: pdev_map_interrupt failed %d\n", __func__, status);
            return status;
        }

        EnableLocked(true);

        auto start_thread = [](void* arg) { return static_cast<AmlUart*>(arg)->IrqThread(); };
        int rc = thrd_create_with_name(&irq_thread_, start_thread, this, "aml_uart_irq_thread");
        if (rc != thrd_success) {
            EnableLocked(false);
            return thrd_status_to_zx_status(rc);
        }
    } else if (!enable && enabled_) {
        irq_.destroy();
        thrd_join(irq_thread_, nullptr);
        EnableLocked(false);
    }

    enabled_ = enable;
    return ZX_OK;
}
示例#13
0
文件: test.c 项目: Walkerks/locks
static void test_mutex_timed(void)
{
  struct TestMutexTimedData data;
  thrd_t thread;
  struct timespec interval = { 0, };
  struct timespec start;
  struct timespec end;

  interval.tv_sec = 0;
  interval.tv_nsec = (NSECS_PER_SECOND / 10) * 2;

  mtx_init(&(data.mutex), mtx_timed);
  mtx_lock(&(data.mutex));

  timespec_get(&(data.start), TIME_UTC);
  data.timeout = data.start;
  timespec_add_nsec(&(data.timeout), NSECS_PER_SECOND / 10);
  data.end = data.timeout;
  timespec_add_nsec(&(data.end), NSECS_PER_SECOND / 10);
  data.upper = data.end;
  timespec_add_nsec(&(data.upper), NSECS_PER_SECOND / 10);

  thrd_create(&thread, test_mutex_timed_thread_func, &data);

  timespec_get(&start, TIME_UTC);
  assert (thrd_sleep(&interval, &interval) == 0);
  timespec_get(&end, TIME_UTC);
  mtx_unlock(&(data.mutex));

  thrd_join(thread, NULL);
}
示例#14
0
文件: main.c 项目: ucf-cs/CCSpec
int user_main(int argc, char **argv)
{
    int i;
    int *param;
    unsigned int in_sum = 0, out_sum = 0;

    atomic_init(&x[1], 0);
    atomic_init(&x[2], 0);

    stack = (stack_t*) calloc(1, sizeof(*stack));

    num_threads = procs;
    threads = (thrd_t*) malloc(num_threads * sizeof(thrd_t));
    param = (int*) malloc(num_threads * sizeof(*param));

    init_stack(stack, num_threads);

    for (i = 0; i < num_threads; i++) {
        param[i] = i;
        thrd_create(&threads[i], main_task, &param[i]);
    }
    for (i = 0; i < num_threads; i++)
        thrd_join(threads[i]);

    bool correct = false;
    //correct |= (a == 17 || a == 37 || a == 0);
    //MODEL_ASSERT(correct);

    free(param);
    free(threads);
    free(stack);

    return 0;
}
THREADAPI_RESULT ThreadAPI_Join(THREAD_HANDLE threadHandle, int *res)
{
    THREADAPI_RESULT result;
    thrd_t* thrd_t_ptr = (thrd_t*)threadHandle;

    if (threadHandle == NULL)
    {
        result = THREADAPI_INVALID_ARG;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(THREADAPI_RESULT, result));
    }
    else
    {
        switch (thrd_join(*thrd_t_ptr, res))
        {
        default:
        case thrd_error:
            result = THREADAPI_ERROR;
            LogError("(result = %s)\r\n", ENUM_TO_STRING(THREADAPI_RESULT, result));
            break;

        case thrd_success:
            result = THREADAPI_OK;
            break;

        case thrd_nomem:
            result = THREADAPI_NO_MEMORY;
            LogError("(result = %s)\r\n", ENUM_TO_STRING(THREADAPI_RESULT, result));
            break;
        }

        free(thrd_t_ptr);
    }

    return result;
}
示例#16
0
main()
{
    thrd_t thrd1;
    printf("%d\n", mtx_init(&mtx1, mtx_plain));
    thrd_create(&thrd1, thread1, 0);
    thrd_join(thrd1, NULL);
    mtx_destroy(&mtx1);

    printf("\n%d\n", mtx_init(&mtx1, mtx_plain | mtx_recursive));
    thrd_create(&thrd1, thread1, 0);
    thrd_join(thrd1, NULL);
    mtx_destroy(&mtx1);

    mtx_init(&mtx1, mtx_try);
    thrd_create(&thrd1, thread3, 0); 
    Sleep(500);
    printf("%d\n", mtx_trylock(&mtx1));
    xtime xt;
    xtime_get(&xt, TIME_UTC);
    xt.nsec += 200000000;
    printf("%d\n", mtx_timedlock(&mtx1, &xt));
    xt.nsec += 500000000;
    printf("%d\n", mtx_timedlock(&mtx1, &xt));
    mtx_unlock(&mtx1);
    printf("%d\n", mtx_trylock(&mtx1));
    mtx_unlock(&mtx1);
    
    thrd_create(&thrd1, thread4, 0);
    thrd_detach(thrd1);
    thrd_create(&thrd1, thread5, 0);
    thrd_join(thrd1, NULL);
        
    thrd_create(&thrd1, thread2, 0);
    thrd_detach(thrd1);
    thrd_create(&thrd1, thread2, (void *)1);
    thrd_detach(thrd1);
    Sleep(4000);

    thrd_create(&thrd1, thread2, (void *)2);
    thrd_detach(thrd1);
    thrd_create(&thrd1, thread2, (void *)3);
    thrd_detach(thrd1);
    Sleep(4000);
    
    mtx_destroy(&mtx1);

}
示例#17
0
bool c11_thread_test(void) {
    BEGIN_TEST;

    thrd_t thread;
    int return_value = 99;

    unittest_printf("Welcome to thread test!\n");

    memset((void*)threads_done, 0, sizeof(threads_done));
    for (int i = 0; i != 4; ++i) {
        int return_value = 99;
        int ret = thrd_create_with_name(&thread, thread_entry, (void*)(intptr_t)i, "c11 thread test");
        ASSERT_EQ(ret, thrd_success, "Error while creating thread");

        ret = thrd_join(thread, &return_value);
        ASSERT_EQ(ret, thrd_success, "Error while thread join");
        ASSERT_EQ(return_value, i, "Incorrect return from thread");
    }

    unittest_printf("Attempting to create thread with a null name. This should succeed\n");
    int ret = thrd_create_with_name(&thread, thread_entry, (void*)(intptr_t)4, NULL);
    ASSERT_EQ(ret, thrd_success, "Error returned from thread creation");
    zx_handle_t handle = thrd_get_zx_handle(thread);
    ASSERT_NE(handle, ZX_HANDLE_INVALID, "got invalid thread handle");
    // Prove this is a valid handle by duplicating it.
    zx_handle_t dup_handle;
    zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &dup_handle);
    ASSERT_EQ(status, 0, "failed to duplicate thread handle");

    ret = thrd_join(thread, &return_value);
    ASSERT_EQ(ret, thrd_success, "Error while thread join");
    ASSERT_EQ(zx_handle_close(dup_handle), ZX_OK, "failed to close duplicate handle");
    ASSERT_EQ(return_value, 4, "Incorrect return from thread");

    ret = thrd_create_with_name(&thread, thread_entry, (void*)(intptr_t)5, NULL);
    ASSERT_EQ(ret, thrd_success, "Error returned from thread creation");
    ret = thrd_detach(thread);
    ASSERT_EQ(ret, thrd_success, "Error while thread detach");

    while (!threads_done[5])
        zx_nanosleep(zx_deadline_after(ZX_MSEC(100)));

    thread_entry((void*)(intptr_t)6);
    ASSERT_TRUE(threads_done[6], "All threads should have completed");

    END_TEST;
}
示例#18
0
文件: threads.c 项目: eledot/Plum
int main(void)
{
    int i, result;
    Thread threads[] =
    {
        { NULL, "Red", 1.f, 0.f, 0.f, 0 },
        { NULL, "Green", 0.f, 1.f, 0.f, 0 },
        { NULL, "Blue", 0.f, 0.f, 1.f, 0 }
    };
    const int count = sizeof(threads) / sizeof(Thread);

    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW: %s\n",
                glfwErrorString(glfwGetError()));
        exit(EXIT_FAILURE);
    }

    for (i = 0;  i < count;  i++)
    {
        glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i);
        glfwWindowHint(GLFW_POSITION_Y, 200);
        threads[i].window = glfwCreateWindow(200, 200,
                                             GLFW_WINDOWED,
                                             threads[i].title,
                                             NULL);
        if (!threads[i].window)
        {
            fprintf(stderr, "Failed to open GLFW window: %s\n",
                    glfwErrorString(glfwGetError()));
            exit(EXIT_FAILURE);
        }

        if (thrd_create(&threads[i].id, thread_main, threads + i) !=
            thrd_success)
        {
            fprintf(stderr, "Failed to create secondary thread\n");
            exit(EXIT_FAILURE);
        }
    }

    while (running)
    {
        assert(glfwGetCurrentContext() == NULL);

        glfwWaitEvents();

        for (i = 0;  i < count;  i++)
        {
            if (glfwGetWindowParam(threads[i].window, GLFW_CLOSE_REQUESTED))
                running = GL_FALSE;
        }
    }

    for (i = 0;  i < count;  i++)
        thrd_join(threads[i].id, &result);

    exit(EXIT_SUCCESS);
}
示例#19
0
int user_main(int argc, char **argv)
{
	thrd_t t1, t2;

	atomic_init(&x, -1);
	atomic_init(&y, 0);

	printf("Main thread: creating 2 threads\n");
	thrd_create(&t1, (thrd_start_t)&a, NULL);
	thrd_create(&t2, (thrd_start_t)&b, NULL);

	thrd_join(t1);
	thrd_join(t2);
	printf("Main thread is finished\n");

	return 0;
}
示例#20
0
文件: test.c 项目: Walkerks/locks
static void test_thrd_exit(void)
{
  thrd_t thread;
  int res;
  thrd_create(&thread, test_thrd_exit_func, NULL);
  assert(thrd_join(thread, &res));
  assert(res == 2);
}
示例#21
0
int main(void){
      int threadId;
      int retval;
      thrd_create(&threadId, f, NULL);
      thrd_join(threadId, &retval); // thread f is now dead
      *sneaky;
      return 0;
}
int user_main(int argc, char **argv)
{
	thrd_t t1, t2, t5;
	int i = 4;

	atomic_init(&x, 0);

	thrd_create(&t1, (thrd_start_t)&a, &i);
	thrd_create(&t2, (thrd_start_t)&b1, NULL);
	thrd_create(&t5, (thrd_start_t)&c, NULL);

	thrd_join(t1);
	thrd_join(t2);
	thrd_join(t5);

	return 0;
}
示例#23
0
int main(void)
{
    int i, result;
    Thread threads[] =
    {
        { NULL, "Red", 1.f, 0.f, 0.f, 0 },
        { NULL, "Green", 0.f, 1.f, 0.f, 0 },
        { NULL, "Blue", 0.f, 0.f, 1.f, 0 }
    };
    const int count = sizeof(threads) / sizeof(Thread);

    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_VISIBLE, GL_FALSE);

    for (i = 0;  i < count;  i++)
    {
        threads[i].window = glfwCreateWindow(200, 200,
                                             threads[i].title,
                                             NULL, NULL);
        if (!threads[i].window)
        {
            glfwTerminate();
            exit(EXIT_FAILURE);
        }

        glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200);
        glfwShowWindow(threads[i].window);

        if (thrd_create(&threads[i].id, thread_main, threads + i) !=
            thrd_success)
        {
            fprintf(stderr, "Failed to create secondary thread\n");

            glfwTerminate();
            exit(EXIT_FAILURE);
        }
    }

    while (running)
    {
        glfwWaitEvents();

        for (i = 0;  i < count;  i++)
        {
            if (glfwWindowShouldClose(threads[i].window))
                running = GL_FALSE;
        }
    }

    for (i = 0;  i < count;  i++)
        thrd_join(threads[i].id, &result);

    exit(EXIT_SUCCESS);
}
示例#24
0
int user_main(int argc, char **argv)
{
	thrd_t t1, t2;

	if (argc > 1)
		N = atoi(argv[1]);

	atomic_init(&x, 0);
	thrd_create(&t1, (thrd_start_t)&a, NULL);
	thrd_create(&t2, (thrd_start_t)&a, NULL);

	thrd_join(t1);
	thrd_join(t2);

	MODEL_ASSERT(atomic_load(&x) == N * 2);

	return 0;
}
示例#25
0
int main(int argc, char *argv[])
{
   thrd_t thread1;

   thrd_create( &thread1, func_thrd, NULL);

   thrd_join( thread1, NULL);

   return EXIT_SUCCESS;
}
示例#26
0
static void testTwoThreads()
{
    start_test("Lock free FIFO - producer/consumer threads");
    
    //TODO: actually check stuff
    const int es = sizeof(int);
    const int c = 100;
    
    drLockFreeFIFO f;
    drLockFreeFIFO_init(&f, c, es);
    
    thrd_t t1, t2;
    thrd_create(&t1, entryPointConsumer, &f);
    thrd_create(&t2, entryPointProducer, &f);
    
    int joinRes1, joinRes2;
    thrd_join(t1, &joinRes1);
    thrd_join(t2, &joinRes2);
}
示例#27
0
int main(void) {
#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);
    printf("atomic %u\n", acnt);
    printf("non-atomic %u\n", cnt);
#endif
}
示例#28
0
文件: client.c 项目: CouleeApps/Craft
void client_stop() {
    if (!client_enabled) {
        return;
    }
    close(sd);
    if (thrd_join(recv_thread, NULL) != thrd_success) {
        perror("thrd_join");
        exit(1);
    }
    mtx_destroy(&mutex);
}
示例#29
0
文件: main.c 项目: wuwx/simba
int test_suspend_resume(struct harness_t *harness_p)
{
    int err;
    struct thrd_t *thrd_p;

    thrd_p = thrd_spawn(suspend_resume_main,
                        thrd_self(),
                        10,
                        suspend_resume_stack,
                        sizeof(suspend_resume_stack));

    err = thrd_suspend(NULL);
    BTASSERT(err == 3);

    /* Wait for the spawned thread to terminate, twice. */
    BTASSERT(thrd_join(thrd_p) == 0);
    BTASSERT(thrd_join(thrd_p) == 0);

    return (0);
}
示例#30
0
void closeUartOutput(flowOutputState state) {
	state->running = false;
	uart_close();

	if ((errno = thrd_join(state->thread, NULL)) != thrd_success) {
		// This should never happen!
		caerLog(CAER_LOG_CRITICAL, SUBSYSTEM_UART,
				"Failed to join output handling thread. Error: %d.", errno);
	}
	ringBufferFree(state->buffer);
}