Process-in-Process
 All Functions Groups Pages
pip_blt.h
1 /*
2  * $PIP_license: <Simplified BSD License>
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are met:
5  *
6  * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  *
9  * Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  * $
25  * $RIKEN_copyright: Riken Center for Computational Sceience (R-CCS),
26  * System Software Development Team, 2016-2021
27  * $
28  * $PIP_VERSION: Version 3.1.0$
29  *
30  * $Author: Atsushi Hori (R-CCS)
31  * Query: procinproc-info@googlegroups.com
32  * User ML: procinproc-users@googlegroups.com
33  * $
34  */
35 
36 #ifndef _pip_blt_h_
37 #define _pip_blt_h_
38 
39 #ifndef DOXYGEN_INPROGRESS
40 
41 #include <pip/pip_machdep.h>
42 #include <string.h>
43 
44 #define PIP_SYNC_AUTO (0x0001U)
45 #define PIP_SYNC_BUSYWAIT (0x0002U)
46 #define PIP_SYNC_YIELD (0x0004U)
47 #define PIP_SYNC_BLOCKING (0x0008U)
48 
49 #define PIP_SYNC_MASK (PIP_SYNC_AUTO | \
50  PIP_SYNC_BUSYWAIT | \
51  PIP_SYNC_YIELD | \
52  PIP_SYNC_BLOCKING)
53 
54 #define PIP_TASK_INACTIVE (0x01000U)
55 #define PIP_TASK_ACTIVE (0x02000U)
56 
57 #define PIP_TASK_MASK \
58  (PIP_TASK_INACTIVE|PIP_TASK_ACTIVE)
59 
60 #define PIP_TASK_ALL (-1)
61 
62 #define PIP_YIELD_DEFAULT (0x0U)
63 #define PIP_YIELD_USER (0x1U)
64 #define PIP_YIELD_SYSTEM (0x2U)
65 
66 #define PIP_ENV_SYNC "PIP_SYNC"
67 #define PIP_ENV_SYNC_AUTO "auto"
68 #define PIP_ENV_SYNC_BUSY "busy"
69 #define PIP_ENV_SYNC_BUSYWAIT "busywait"
70 #define PIP_ENV_SYNC_YIELD "yield"
71 #define PIP_ENV_SYNC_BLOCK "block"
72 #define PIP_ENV_SYNC_BLOCKING "blocking"
73 
74 typedef struct pip_task {
75  struct pip_task *next;
76  struct pip_task *prev;
77 } pip_task_t;
78 
79 #define PIP_TASKQ_NEXT(L) (((pip_task_t*)(L))->next)
80 #define PIP_TASKQ_PREV(L) (((pip_task_t*)(L))->prev)
81 #define PIP_TASKQ_PREV_NEXT(L) (((pip_task_t*)(L))->prev->next)
82 #define PIP_TASKQ_NEXT_PREV(L) (((pip_task_t*)(L))->next->prev)
83 
84 #define PIP_TASKQ_INIT(L) \
85  do { PIP_TASKQ_NEXT(L) = PIP_TASKQ_PREV(L) = \
86  (pip_task_t*)(L); } while(0)
87 
88 #define PIP_TASKQ_ENQ_FIRST(L,E) \
89  do { PIP_TASKQ_NEXT(E) = PIP_TASKQ_NEXT(L); \
90  PIP_TASKQ_PREV(E) = (pip_taskt*)(L); \
91  PIP_TASKQ_NEXT_PREV(L) = (pip_task_t*)(E); \
92  PIP_TASKQ_NEXT(L) = (pip_task_t*)(E); } while(0)
93 
94 #define PIP_TASKQ_ENQ_LAST(L,E) \
95  do { PIP_TASKQ_NEXT(E) = (pip_task_t*)(L); \
96  PIP_TASKQ_PREV(E) = PIP_TASKQ_PREV(L); \
97  PIP_TASKQ_PREV_NEXT(L) = (pip_task_t*)(E); \
98  PIP_TASKQ_PREV(L) = (pip_task_t*)(E); } while(0)
99 
100 #define PIP_TASKQ_DEQ(E) \
101  do { PIP_TASKQ_NEXT_PREV(E) = PIP_TASKQ_PREV(E); \
102  PIP_TASKQ_PREV_NEXT(E) = PIP_TASKQ_NEXT(E); \
103  PIP_TASKQ_INIT(E); } while(0)
104 
105 #define PIP_TASKQ_APPEND(P,Q) \
106  do { if( !PIP_TASKQ_ISEMPTY(Q) ) { \
107  PIP_TASKQ_NEXT_PREV(Q) = PIP_TASKQ_PREV(P); \
108  PIP_TASKQ_PREV_NEXT(Q) = (P); \
109  PIP_TASKQ_PREV_NEXT(P) = PIP_TASKQ_NEXT(Q); \
110  PIP_TASKQ_PREV(P) = PIP_TASKQ_PREV(Q); \
111  PIP_TASKQ_INIT(Q); } } while(0)
112 
113 #define PIP_TASKQ_ISEMPTY(L) \
114  ( PIP_TASKQ_NEXT(L) == (L) && PIP_TASKQ_PREV(L) == (pip_task_t*)(L) )
115 
116 #define PIP_TASKQ_FOREACH(L,E) \
117  for( (E)=PIP_TASKQ_NEXT(L); (pip_task_t*)(L)!=(E); \
118  (E)=PIP_TASKQ_NEXT(E) )
119 
120 #define PIP_TASKQ_FOREACH_SAFE(L,E,TV) \
121  for( (E)=PIP_TASKQ_NEXT(L), (TV)=PIP_TASKQ_NEXT(E); \
122  (pip_task_t*)(L)!=(E); \
123  (E)=(TV), (TV)=PIP_TASKQ_NEXT(TV) )
124 
125 #define PIP_TASKQ_MOVE(D,S) \
126  do { if( PIP_TASKQ_ISEMPTY(S) ) { \
127  PIP_TASKQ_INIT(D); \
128  } else { \
129  (D)->next = (S)->next; \
130  (D)->prev = (S)->prev; \
131  PIP_TASKQ_INIT(S); } } while(0)
132 
133 
134 typedef pip_task_t pip_list_t;
135 
136 /* aliases */
137 #define PIP_LIST_INIT(L) PIP_TASKQ_INIT(L)
138 #define PIP_LIST_ISEMPTY(L) PIP_TASKQ_ISEMPTY(L)
139 #define PIP_LIST_ADD(L,E) PIP_TASKQ_ENQ_LAST(L,E)
140 #define PIP_LIST_DEL(E) PIP_TASKQ_DEQ(E)
141 #define PIP_LIST_FOREACH(L,E) PIP_TASKQ_FOREACH(L,E)
142 #define PIP_LIST_FOREACH_SAFE(L,E,F) PIP_TASKQ_FOREACH_SAFE(L,E,F)
143 #define PIP_LIST_MOVE(D,S) PIP_TASKQ_MOVE(D,S)
144 
145 struct pip_task_queue_methods;
146 
147 typedef struct pip_task_queue {
148  volatile pip_task_t queue;
149  struct pip_task_queue_methods *methods;
150  pip_spinlock_t lock;
151  volatile uint32_t length;
152  void *aux;
153 } pip_task_queue_t;
154 
155 typedef void(*pip_enqueue_callback_t)(void*);
156 
157 #define PIP_CB_UNLOCK_AFTER_ENQUEUE ((pip_enqueue_callback_t)1)
158 
159 typedef int (*pip_task_queue_init_t) (void*);
160 typedef void (*pip_task_queue_lock_t) (void*);
161 typedef int (*pip_task_queue_trylock_t) (void*);
162 typedef void (*pip_task_queue_unlock_t) (void*);
163 typedef int (*pip_task_queue_isempty_t) (void*);
164 typedef int (*pip_task_queue_count_t) (void*, int*);
165 typedef void (*pip_task_queue_enqueue_t) (void*, pip_task_t*);
166 typedef pip_task_t *(*pip_task_queue_dequeue_t) (void*);
167 typedef void (*pip_task_queue_describe_t) (void*,FILE*);
168 typedef int (*pip_task_queue_fin_t) (void*);
169 
170 typedef struct pip_task_queue_methods {
171  pip_task_queue_init_t init;
172  pip_task_queue_lock_t lock;
173  pip_task_queue_trylock_t trylock;
174  pip_task_queue_unlock_t unlock;
175  pip_task_queue_isempty_t isempty;
176  pip_task_queue_count_t count;
177  pip_task_queue_enqueue_t enqueue;
178  pip_task_queue_dequeue_t dequeue;
179  pip_task_queue_fin_t fin;
180  pip_task_queue_describe_t describe;
181 } pip_task_queue_methods_t;
182 
183 typedef struct pip_barrier {
184  pip_atomic_t count_init;
185  pip_atomic_t count;
186  pip_task_queue_t queue; /* this must be placed at the end */
187 } pip_barrier_t;
188 
189 typedef struct pip_mutex {
190  pip_atomic_t count;
191  pip_task_queue_t queue; /* this must be placed at the end */
192 } pip_mutex_t;
193 
194 #define PIP_QUEUE_TYPEDEF(N,B) \
195  typedef struct N { \
196  pip_task_queue_t pip_queue; \
197  B; \
198  } N;
199 
200 #define PIP_MUTEX_TYPEDEF(N,B) \
201  typedef struct N { \
202  pip_mutex_t pip_mutex; \
203  B; \
204  } N;
205 
206 #define PIP_BARTIER_TYPEDEF(N,B) \
207  typedef struct N { \
208  pip_barrier_t pip_barrier; \
209  B; \
210  } N;
211 
212 #endif /* DOXYGEN */
213 
214 #ifdef DOXYGEN_INPROGRESS
215 #ifndef INLINE
216 #define INLINE
217 #endif
218 #else
219 #ifndef INLINE
220 #define INLINE inline static
221 #endif
222 #endif
223 
224 #ifndef DOXYGEN_INPROGRESS
225 #ifdef __cplusplus
226 extern "C" {
227 #endif
228 
229  int pip_task_str( char*, size_t, pip_task_t* );
230 
231 #endif
232 
349 #ifdef DOXYGEN_INPROGRESS
350 int pip_blt_spawn( pip_spawn_program_t *progp,
351  uint32_t coreno,
352  uint32_t opts,
353  int *pipidp,
354  pip_task_t **bltp,
355  pip_task_queue_t *queue,
356  pip_spawn_hook_t *hookp );
357 #else
358 int pip_blt_spawn_( pip_spawn_program_t *progp,
359  uint32_t coreno,
360  uint32_t opts,
361  int *pipidp,
362  pip_task_t **bltp,
363  pip_task_queue_t *queue,
364  pip_spawn_hook_t *hookp );
365 #define pip_blt_spawn( progp, coreno, opts, pipid, bltp, queue, hookp ) \
366  pip_blt_spawn_( (progp), (coreno), (opts), (pipid), (bltp), \
367  (pip_task_queue_t*) (queue), (hookp) )
368 #endif
369 
405  int pip_yield( int flag );
406 
431  int pip_yield_to( pip_task_t *task );
432 
459 #ifdef DOXYGEN_INPROGRESS
460  int pip_task_queue_init( pip_task_queue_t *queue,
461  pip_task_queue_methods_t *methods );
462 #else
463  INLINE int pip_task_queue_init_( pip_task_queue_t *queue,
464  pip_task_queue_methods_t *methods ) {
465  if( queue == NULL ) return EINVAL;
466  queue->methods = methods;
467  if( methods == NULL || methods->init == NULL) {
468  PIP_TASKQ_INIT( &queue->queue );
469  pip_spin_init( &queue->lock );
470  queue->methods = NULL;
471  queue->length = 0;
472  queue->aux = NULL;
473  return 0;
474  } else {
475  return methods->init( queue );
476  }
477  }
478 #define pip_task_queue_init( Q, M ) \
479  pip_task_queue_init_( (pip_task_queue_t*)(Q), (M) )
480 #endif
481 
495 #ifdef DOXYGEN_INPROGRESS
496  int pip_task_queue_trylock( pip_task_queue_t *queue );
497 #else
498  INLINE int pip_task_queue_trylock_( pip_task_queue_t *queue ) {
499  if( queue == NULL ) return EINVAL;
500  if( queue->methods == NULL || queue->methods->trylock == NULL ) {
501  return pip_spin_trylock( &queue->lock );
502  } else {
503  return queue->methods->trylock( (void*) queue );
504  }
505  }
506 #define pip_task_queue_trylock( Q ) \
507  pip_task_queue_trylock_( (pip_task_queue_t*)(Q) )
508 #endif
509 
523 #ifdef DOXYGEN_INPROGRESS
524  void pip_task_queue_lock( pip_task_queue_t *queue );
525 #else
526  INLINE void pip_task_queue_lock_( pip_task_queue_t *queue ) {
527  if( queue == NULL ) return;
528  if( queue->methods == NULL || queue->methods->lock == NULL ) {
529  while( !pip_spin_trylock( &queue->lock ) ) {
530  (void) pip_pause();
531  }
532  } else {
533  queue->methods->lock( queue );
534  }
535  }
536 #define pip_task_queue_lock( Q ) \
537  pip_task_queue_lock_( (pip_task_queue_t*)(Q) )
538 #endif
539 
553 #ifdef DOXYGEN_INPROGRESS
554  void pip_task_queue_unlock( pip_task_queue_t *queue );
555 #else
556  INLINE void pip_task_queue_unlock_( pip_task_queue_t *queue ) {
557  if( queue == NULL ) return;
558  if( queue->methods == NULL || queue->methods->unlock == NULL ) {
559  pip_spin_unlock( &queue->lock );
560  } else {
561  queue->methods->unlock( (void*) queue );
562  }
563  }
564 #define pip_task_queue_unlock( Q ) \
565  pip_task_queue_unlock_( (pip_task_queue_t*)(Q) )
566 #endif
567 
582 #ifdef DOXYGEN_INPROGRESS
583  int pip_task_queue_isempty( pip_task_queue_t *queue );
584 #else
585  INLINE int pip_task_queue_isempty_( pip_task_queue_t *queue ) {
586  if( queue->methods == NULL || queue->methods->isempty == NULL ) {
587  return PIP_TASKQ_ISEMPTY( &queue->queue );
588  } else {
589  return queue->methods->isempty( (void*) queue );
590  }
591  }
592 #define pip_task_queue_isempty( Q ) \
593  pip_task_queue_isempty_( (pip_task_queue_t*)(Q) )
594 #endif
595 
612 #ifdef DOXYGEN_INPROGRESS
613  int pip_task_queue_count( pip_task_queue_t *queue, int *np );
614 #else
615  INLINE int
616  pip_task_queue_count_( pip_task_queue_t *queue, int *np ) {
617  int err = 0;
618  if( queue == NULL ) return EINVAL;
619  if( np == NULL ) return EINVAL;
620  if( queue->methods == NULL || queue->methods->count == NULL ) {
621  *np = queue->length;
622  } else {
623  err = queue->methods->count( queue, np );
624  }
625  return err;
626  }
627 #define pip_task_queue_count( Q, NP ) \
628  pip_task_queue_count_( (pip_task_queue_t*)(Q), (NP) )
629 #endif
630 
647 #ifdef DOXYGEN_INPROGRESS
648  void pip_task_queue_enqueue( pip_task_queue_t *queue, pip_task_t *task );
649 #else
650  INLINE void
651  pip_task_queue_enqueue_( pip_task_queue_t *queue, pip_task_t *task ) {
652  if( queue == NULL ) return;
653  if( queue->methods == NULL || queue->methods->enqueue == NULL ) {
654  PIP_TASKQ_ENQ_LAST( &queue->queue, task );
655  queue->length ++;
656  } else {
657  queue->methods->enqueue( (void*) queue, task );
658  }
659  }
660 #define pip_task_queue_enqueue( Q, T ) \
661  pip_task_queue_enqueue_( (pip_task_queue_t*) (Q), (T) )
662 #endif
663 
681 #ifdef DOXYGEN_INPROGRESS
682  pip_task_t* pip_task_queue_dequeue( pip_task_queue_t *queue );
683 #else
684  INLINE pip_task_t*
685  pip_task_queue_dequeue_( pip_task_queue_t *queue ) {
686  if( queue == NULL ) return NULL;
687  if( queue->methods == NULL || queue->methods->dequeue == NULL ) {
688  pip_task_t *first;
689  if( PIP_TASKQ_ISEMPTY( &queue->queue ) ) return NULL;
690  first = PIP_TASKQ_NEXT( &queue->queue );
691  PIP_TASKQ_DEQ( first );
692  queue->length --;
693  return first;
694  } else {
695  return queue->methods->dequeue( (void*) queue );
696  }
697  }
698 #define pip_task_queue_dequeue( Q ) \
699  pip_task_queue_dequeue_( (pip_task_queue_t*) (Q) )
700 #endif
701 
714 #ifdef DOXYGEN_INPROGRESS
715  void pip_task_queue_describe( pip_task_queue_t *queue, FILE *fp );
716 #else
717  INLINE void
718  pip_task_queue_describe_( pip_task_queue_t *queue, char *tag, FILE *fp ) {
719  if( queue == NULL ) return;
720  if( queue->methods == NULL || queue->methods->describe == NULL ) {
721  if( PIP_TASKQ_ISEMPTY( &queue->queue ) ) {
722  fprintf( fp, "%s: Queue is (EMPTY)\n", tag );
723  } else {
724  pip_task_t *task;
725  char msg[256];
726  int i = 0;
727  PIP_TASKQ_FOREACH( &queue->queue, task ) {
728  (void) pip_task_str( msg, sizeof(msg), task );
729  fprintf( fp, "%s: Queue[%d/%d]:%s\n", tag, i++, queue->length, msg );
730  }
731  }
732  } else {
733  queue->methods->describe( (void*) queue, fp );
734  }
735  }
736 #define pip_task_queue_describe( Q, T, F ) \
737  pip_task_queue_describe_( (pip_task_queue_t*)(Q), (T), (F) )
738 #endif
739 
753 #ifdef DOXYGEN_INPROGRESS
754  int pip_task_queue_fin( pip_task_queue_t *queue );
755 #else
756  INLINE int pip_task_queue_fin_( pip_task_queue_t *queue ) {
757  if( queue == NULL ) return EINVAL;
758  if( queue->methods == NULL || queue->methods->fin == NULL ) {
759  if( !PIP_TASKQ_ISEMPTY( &queue->queue ) ) return EBUSY;
760  return 0;
761  } else {
762  return queue->methods->fin( (void*) queue );
763  }
764  }
765 #define pip_task_queue_fin( Q ) \
766  pip_task_queue_fin_( (pip_task_queue_t*)(Q) )
767 #endif
768 
813 #ifdef DOXYGEN_INPROGRESS
814  int pip_suspend_and_enqueue( pip_task_queue_t *queue,
815  pip_enqueue_callback_t callback,
816  void *cbarg );
817 #else
818  int pip_suspend_and_enqueue_( pip_task_queue_t *queue,
819  pip_enqueue_callback_t callback,
820  void *cbarg );
821 #define pip_suspend_and_enqueue( Q, C, A ) \
822  pip_suspend_and_enqueue_( (pip_task_queue_t*)(Q), (C), (A) )
823 #endif
824 
855 #ifdef DOXYGEN_INPROGRESS
856  int pip_suspend_and_enqueue_nolock( pip_task_queue_t *queue,
857  pip_enqueue_callback_t callback,
858  void *cbarg );
859 #else
860  int pip_suspend_and_enqueue_nolock_( pip_task_queue_t *queue,
861  pip_enqueue_callback_t callback,
862  void *cbarg );
863 #define pip_suspend_and_enqueue_nolock( Q, C, A ) \
864  pip_suspend_and_enqueue_nolock_( (pip_task_queue_t*)(Q), (C), (A) )
865 #endif
866 
888 #ifdef DOXYGEN_INPROGRESS
889  int pip_dequeue_and_resume( pip_task_queue_t *queue, pip_task_t *sched );
890 #else
891  int pip_dequeue_and_resume_( pip_task_queue_t *queue, pip_task_t *sched );
892 #define pip_dequeue_and_resume( Q, S ) \
893  pip_dequeue_and_resume_( (pip_task_queue_t*)(Q), (S) )
894 #endif
895 
923 #ifdef DOXYGEN_INPROGRESS
924  int pip_dequeue_and_resume_nolock( pip_task_queue_t *queue,
925  pip_task_t *sched );
926 #else
927  int pip_dequeue_and_resume_nolock_( pip_task_queue_t *queue,
928  pip_task_t *sched );
929 #define pip_dequeue_and_resume_nolock( Q, S ) \
930  pip_dequeue_and_resume_nolock_( (pip_task_queue_t*)(Q), (S) )
931 #endif
932 
968 #ifdef DOXYGEN_INPROGRESS
969  int pip_dequeue_and_resume_N( pip_task_queue_t *queue,
970  pip_task_t *sched,
971  int *np );
972 #else
973  int pip_dequeue_and_resume_N_( pip_task_queue_t *queue,
974  pip_task_t *sched,
975  int *np );
976 #define pip_dequeue_and_resume_N( Q, S, N ) \
977  pip_dequeue_and_resume_N_( (pip_task_queue_t*)(Q), (S), (N) )
978 
979 #endif
980 
1013 #ifdef DOXYGEN_INPROGRESS
1014  int pip_dequeue_and_resume_N_nolock( pip_task_queue_t *queue,
1015  pip_task_t *sched,
1016  int *np );
1017 #else
1018  int pip_dequeue_and_resume_N_nolock_( pip_task_queue_t *queue,
1019  pip_task_t *sched, int *np );
1020 #define pip_dequeue_and_resume_N_nolock( Q, S, N ) \
1021  pip_dequeue_and_resume_N_nolock_( (pip_task_queue_t*)(Q), (S), (N) )
1022 #endif
1023 
1047  pip_task_t *pip_task_self( void );
1048 
1066  int pip_get_task_pipid( pip_task_t *task, int *pipidp );
1067 
1086  int pip_get_task_by_pipid( int pipid, pip_task_t **taskp );
1087 
1103  int pip_get_sched_domain( pip_task_t **domainp );
1138 #ifdef DOXYGEN_INPROGRESS
1139  int pip_barrier_init( pip_barrier_t *barrp, int n );
1140 #else
1141  int pip_barrier_init_( pip_barrier_t *barrp, int n );
1142 #define pip_barrier_init( B, N ) \
1143  pip_barrier_init_( (pip_barrier_t*)(B), (N) )
1144 #endif
1145 
1166 #ifdef DOXYGEN_INPROGRESS
1167  int pip_barrier_wait( pip_barrier_t *barrp );
1168 #else
1169  int pip_barrier_wait_( pip_barrier_t *barrp );
1170 #define pip_barrier_wait( B ) \
1171  pip_barrier_wait_( (pip_barrier_t*)(B) )
1172 #endif
1173 
1194 #ifdef DOXYGEN_INPROGRESS
1195  int pip_barrier_fin( pip_barrier_t *barrp );
1196 #else
1197  int pip_barrier_fin_( pip_barrier_t *queue );
1198 #define pip_barrier_fin( B ) \
1199  pip_barrier_fin_( (pip_barrier_t*)(B) )
1200 #endif
1201 
1232 #ifdef DOXYGEN_INPROGRESS
1233  int pip_mutex_init( pip_mutex_t *mutex );
1234 #else
1235  int pip_mutex_init_( pip_mutex_t *mutex );
1236 #define pip_mutex_init( M ) \
1237  pip_mutex_init_( (pip_mutex_t*)(M) )
1238 #endif
1239 
1259 #ifdef DOXYGEN_INPROGRESS
1260  int pip_mutex_lock( pip_mutex_t *mutex );
1261 #else
1262  int pip_mutex_lock_( pip_mutex_t *mutex );
1263 #define pip_mutex_lock( M ) \
1264  pip_mutex_lock_( (pip_mutex_t*)(M) )
1265 #endif
1266 
1286 #ifdef DOXYGEN_INPROGRESS
1287  int pip_mutex_unlock( pip_mutex_t *mutex );
1288 #else
1289  int pip_mutex_unlock_( pip_mutex_t *mutex );
1290 #define pip_mutex_unlock( M ) \
1291  pip_mutex_unlock_( (pip_mutex_t*)(M) )
1292 #endif
1293 
1313 #ifdef DOXYGEN_INPROGRESS
1314  int pip_mutex_fin( pip_mutex_t *mutex );
1315 #else
1316  int pip_mutex_fin_( pip_mutex_t *mutex );
1317 #define pip_mutex_fin( M ) \
1318  pip_mutex_fin_( (pip_mutex_t*)(M) )
1319 #endif
1320 
1345  int pip_couple( void );
1346 
1364  int pip_decouple( pip_task_t *task );
1365 
1370 #ifndef DOXYGEN_INPROGRESS
1371 #ifdef __cplusplus
1372 }
1373 #endif
1374 #endif
1375 
1376 #endif /* _pip_blt_h_ */
int pip_get_task_by_pipid(int pipid, pip_task_t **taskp)
get PiP task from PiP ID
int pip_mutex_fin(pip_mutex_t *mutex)
Finalize PiP mutex.
int pip_suspend_and_enqueue_nolock(pip_task_queue_t *queue, pip_enqueue_callback_t callback, void *cbarg)
suspend the curren task and enqueue it without locking the queue
void pip_task_queue_describe(pip_task_queue_t *queue, FILE *fp)
Describe queue.
int pip_mutex_init(pip_mutex_t *mutex)
Initialize PiP mutex.
int pip_couple(void)
Couple the curren task with the original kernel thread.
pip_task_t * pip_task_queue_dequeue(pip_task_queue_t *queue)
Dequeue a task from a task queue.
int pip_task_queue_count(pip_task_queue_t *queue, int *np)
Count the length of task queue.
int pip_get_task_pipid(pip_task_t *task, int *pipidp)
Return PIPID of a PiP task.
int pip_mutex_lock(pip_mutex_t *mutex)
Lock PiP mutex.
int pip_dequeue_and_resume_nolock(pip_task_queue_t *queue, pip_task_t *sched)
dequeue a task and make it runnable
int pip_dequeue_and_resume_N_nolock(pip_task_queue_t *queue, pip_task_t *sched, int *np)
dequeue tasks and resume the execution of them
int pip_task_queue_isempty(pip_task_queue_t *queue)
Query function if the current task has some tasks to be scheduled with.
int pip_mutex_unlock(pip_mutex_t *mutex)
Unlock PiP mutex.
int pip_dequeue_and_resume(pip_task_queue_t *queue, pip_task_t *sched)
dequeue a task and make it runnable
int pip_get_sched_domain(pip_task_t **domainp)
Return the task representing the scheduling domain.
int pip_barrier_wait(pip_barrier_t *barrp)
wait on barrier synchronization in a busy-wait way int pip_barrier_wait( pip_barrier_t *barrp ); ...
int pip_task_queue_init(pip_task_queue_t *queue, pip_task_queue_methods_t *methods)
Initialize task queue.
void pip_task_queue_enqueue(pip_task_queue_t *queue, pip_task_t *task)
Enqueue a BLT.
int pip_suspend_and_enqueue(pip_task_queue_t *queue, pip_enqueue_callback_t callback, void *cbarg)
suspend the curren task and enqueue it with lock
int pip_dequeue_and_resume_N(pip_task_queue_t *queue, pip_task_t *sched, int *np)
dequeue multiple tasks and resume the execution of them
int pip_decouple(pip_task_t *task)
Decouple the curren task from the kernel thread.
int pip_blt_spawn(pip_spawn_program_t *progp, uint32_t coreno, uint32_t opts, int *pipidp, pip_task_t **bltp, pip_task_queue_t *queue, pip_spawn_hook_t *hookp)
spawn a PiP BLT/ULP (Bi-Level Task / User-Level Process)
int pip_yield(int flag)
Yield.
pip_task_t * pip_task_self(void)
Return the current task.
int pip_barrier_fin(pip_barrier_t *barrp)
finalize barrier synchronization structure
int pip_barrier_init(pip_barrier_t *barrp, int n)
initialize barrier synchronization structure
void pip_task_queue_unlock(pip_task_queue_t *queue)
Unlock task queue.
int pip_task_queue_fin(pip_task_queue_t *queue)
Finalize a task queue.
int pip_task_queue_trylock(pip_task_queue_t *queue)
Try locking task queue.
int pip_yield_to(pip_task_t *task)
Yield to the specified PiP task.
void pip_task_queue_lock(pip_task_queue_t *queue)
Lock task queue.