npv:_reasonable_ "pedanticage" of the code
[nyanmp.git] / npv / thdsws / public / code.frag.c
blobd8ca6b25c4178cf2332b587699da3c7ee31c0bf5
1 #define RUNNING 1
2 STATIC void thdsws_run(struct thdsws_ctx_t *ctx)
4 int r;
5 struct thdsws_ctx_private_t *ctx_priv;
7 ctx_priv = ctx->private;
9 state_lock(ctx_priv);
10 if (ctx_priv->state == RUNNING)
11 fatal("the worker thread is already running, did you forget to wait for it to idle\n");
12 ctx_priv->state = RUNNING;
13 state_unlock(ctx_priv);
14 r = pthread_cond_signal(&ctx_priv->have_fr_to_scale);
15 if (r != 0)
16 fatal("unable to signal the worker thread a frame is to be scaled\n");
18 #undef RUNNING
19 #define RUNNING 1
20 STATIC bool thdsws_is_busy(struct thdsws_ctx_t *ctx)
22 struct thdsws_ctx_private_t *ctx_priv;
23 bool r;
25 ctx_priv = ctx->private;
26 state_lock(ctx_priv);
27 if (ctx_priv->state == RUNNING)
28 r = true;
29 else
30 r = false;
31 state_unlock(ctx_priv);
32 return r;
34 #undef RUNNING
35 #define IDLE 0
36 STATIC struct thdsws_ctx_t *thdsws_init_once(void)
38 int r;
39 pthread_t worker;
40 pthread_attr_t attr;
41 struct thdsws_ctx_t *ctx;
42 struct thdsws_ctx_private_t *ctx_priv;
44 ctx = calloc(1, sizeof(*ctx));
45 if (ctx == 0)
46 fatal("unable to allocate memory for context\n");
47 ctx_priv = calloc(1, sizeof(*ctx_priv));
48 if (ctx_priv == 0)
49 fatal("unable to allocate memory for private context\n");
50 ctx->private = ctx_priv;
52 r = pthread_mutex_init(&ctx_priv->mutex, 0);
53 if (r != 0)
54 fatal("unable to create the state mutex\n");
55 r = pthread_cond_init(&ctx_priv->have_fr_to_scale, 0);
56 if (r != 0)
57 fatal("unable to create waiting condition\n");
59 r = pthread_attr_init(&attr);
60 if (r != 0)
61 fatal("unable to initialize a worker thread attribute\n");
63 r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
64 if (r != 0)
65 fatal("unable to set the worker thread attribute to detach mode\n");
67 /* be really sure the entry state is correct _before_ thd creation */
68 ctx_priv->state = IDLE;
69 r = pthread_create(&worker, &attr, &worker_entry, ctx);
70 if (r != 0)
71 fatal("unable to create the worker thread\n");
72 pthread_attr_destroy(&attr);
73 return ctx;
75 #undef IDLE
76 #define TIME_UNIT_NS 1000000 /* 1ms */
77 #define TIMEOUT_UNITS_N 100 /* 100 * 1 ms = 100 ms */
78 STATIC void thdsws_wait_for_idle(struct thdsws_ctx_t *ctx)
80 u8 nanoloops_n;
82 nanoloops_n = 0;
83 loop {
84 struct timespec ts;
86 if (!thdsws_is_busy(ctx))
87 break;
88 ts.tv_sec = 0;
89 ts.tv_nsec = TIME_UNIT_NS;
90 loop {
91 struct timespec rem;
92 int r;
94 memset(&rem, 0, sizeof(rem));
95 errno = 0;
96 r = nanosleep(&ts, &rem);
97 if (r == 0)
98 break;
99 /* r == -1 */
100 if (errno == EINTR) {
101 memcpy(&ts, &rem, sizeof(ts));
102 continue;
104 fatal("unable to sleep to wait for idle\n");
106 ++nanoloops_n;
107 if (nanoloops_n == TIMEOUT_UNITS_N)
108 fatal("wait for idle timeout\n");
111 #undef TIME_UNIT_NS
112 #undef TIMEOUT_UNITS_N