ARGOBOTS  66b1c39742507d8df30e8d28c54839b961a14814
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
abtd_stream.c
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #include "abti.h"
7 
8 static void *xstream_context_thread_func(void *arg)
9 {
11  void *(*thread_f)(void *) = p_ctx->thread_f;
12  void *p_arg = p_ctx->p_arg;
14  while (1) {
15  /* Execute a main execution stream function. */
16  thread_f(p_arg);
17  /* This thread has finished. */
18  ABT_bool restart;
19  pthread_mutex_lock(&p_ctx->state_lock);
20  /* If another execution stream is waiting for this thread completion,
21  * let's wake it up. */
23  pthread_cond_signal(&p_ctx->state_cond);
24  }
26  /* Wait for a request from ABTD_xstream_context_free() or
27  * ABTD_xstream_context_restart().
28  * The following loop is to deal with spurious wakeup. */
29  do {
30  pthread_cond_wait(&p_ctx->state_cond, &p_ctx->state_lock);
31  } while (p_ctx->state == ABTD_XSTREAM_CONTEXT_STATE_WAITING);
33  /* ABTD_xstream_context_free() terminates this thread. */
34  restart = ABT_FALSE;
35  } else {
36  /* ABTD_xstream_context_restart() restarts this thread */
39  restart = ABT_TRUE;
40  }
41  pthread_mutex_unlock(&p_ctx->state_lock);
42  if (!restart)
43  break;
44  }
45  return NULL;
46 }
47 
48 ABTU_ret_err int ABTD_xstream_context_create(void *(*f_xstream)(void *),
49  void *p_arg,
50  ABTD_xstream_context *p_ctx)
51 {
52  p_ctx->thread_f = f_xstream;
53  p_ctx->p_arg = p_arg;
55  pthread_mutex_init(&p_ctx->state_lock, NULL);
56  pthread_cond_init(&p_ctx->state_cond, NULL);
57  int ret = pthread_create(&p_ctx->native_thread, NULL,
59  if (ret != 0) {
60  HANDLE_ERROR("pthread_create");
61  return ABT_ERR_XSTREAM;
62  }
63  return ABT_SUCCESS;
64 }
65 
67 {
68  /* Request termination */
69  pthread_mutex_lock(&p_ctx->state_lock);
72  pthread_cond_signal(&p_ctx->state_cond);
73  pthread_mutex_unlock(&p_ctx->state_lock);
74  /* Join the target thread. */
75  int ret = pthread_join(p_ctx->native_thread, NULL);
76  ABTI_ASSERT(ret == 0);
77  pthread_cond_destroy(&p_ctx->state_cond);
78  pthread_mutex_destroy(&p_ctx->state_lock);
79 }
80 
82 {
83  /* If not finished, sleep this thread. */
84  pthread_mutex_lock(&p_ctx->state_lock);
88  /* The following loop is to deal with spurious wakeup. */
89  do {
90  pthread_cond_wait(&p_ctx->state_cond, &p_ctx->state_lock);
91  } while (p_ctx->state == ABTD_XSTREAM_CONTEXT_STATE_REQ_JOIN);
92  }
94  pthread_mutex_unlock(&p_ctx->state_lock);
95 }
96 
98 {
99  /* Request restart */
100  pthread_mutex_lock(&p_ctx->state_lock);
103  pthread_cond_signal(&p_ctx->state_cond);
104  pthread_mutex_unlock(&p_ctx->state_lock);
105 }
106 
108 {
109  p_ctx->native_thread = pthread_self();
110 }
pthread_mutex_t state_lock
Definition: abtd.h:26
#define HANDLE_ERROR(msg)
Definition: abti_error.h:37
void ABTD_xstream_context_join(ABTD_xstream_context *p_ctx)
Definition: abtd_stream.c:81
void ABTD_xstream_context_revive(ABTD_xstream_context *p_ctx)
Definition: abtd_stream.c:97
pthread_t native_thread
Definition: abtd.h:22
int ABT_bool
Definition: abt.h:373
#define ABT_FALSE
Definition: abt.h:285
void ABTD_xstream_context_free(ABTD_xstream_context *p_ctx)
Definition: abtd_stream.c:66
#define ABT_SUCCESS
Definition: abt.h:64
ABTU_ret_err int ABTD_xstream_context_create(void *(*f_xstream)(void *), void *p_arg, ABTD_xstream_context *p_ctx)
Definition: abtd_stream.c:48
#define ABT_TRUE
Definition: abt.h:284
void *(* thread_f)(void *)
Definition: abtd.h:23
static void * xstream_context_thread_func(void *arg)
Definition: abtd_stream.c:8
pthread_cond_t state_cond
Definition: abtd.h:27
ABTD_xstream_context_state state
Definition: abtd.h:25
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
void * p_arg
Definition: abtd.h:24
#define ABT_ERR_XSTREAM
Definition: abt.h:94
void ABTD_xstream_context_set_self(ABTD_xstream_context *p_ctx)
Definition: abtd_stream.c:107
#define ABTU_ret_err
Definition: abtu.h:49