P99
p99_iterator.h
Go to the documentation of this file.
1 /* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2 /* */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the author and copyright holder for this work is */
5 /* (C) copyright 2012 Jens Gustedt, INRIA, France */
6 /* */
7 /* This file is free software; it is part of the P99 project. */
8 /* */
9 /* Licensed under the Apache License, Version 2.0 (the "License"); */
10 /* you may not use this file except in compliance with the License. */
11 /* You may obtain a copy of the License at */
12 /* */
13 /* http://www.apache.org/licenses/LICENSE-2.0 */
14 /* */
15 /* Unless required by applicable law or agreed to in writing, software */
16 /* distributed under the License is distributed on an "AS IS" BASIS, */
17 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
18 /* See the License for the specific language governing permissions and */
19 /* limitations under the License. */
20 /* */
21 #ifndef P99_ITERATOR_H
22 #define P99_ITERATOR_H
23 
24 #include "p99_futex.h"
25 
32 
55 struct p99_iterator {
56  unsigned p00_act;
57  p99_futex p00_seen;
58 };
59 
67  if (p00_i) {
68  p00_i->p00_act = 0;
69  p99_futex_init(&p00_i->p00_seen, 0);
70  }
71  return p00_i;
72 }
73 
80  if (p00_i) {
81  p99_futex_destroy(&p00_i->p00_seen);
82  }
83 }
84 
94 P00_FUTEX_INLINE(p99_iterator_next)
96  register unsigned const p00_act = p00_i->p00_act;
97  P99_FUTEX_COMPARE_EXCHANGE(&p00_i->p00_seen, p00_seen,
98  /* wait for more events than we have
99  already processed */
100  (p00_act < p00_seen),
101  /* never update */
102  p00_seen,
103  /* never wakeup others */
104  0u, 0u);
105  p00_i->p00_act = p00_act + 1;
106  return p00_act;
107 }
108 
116 unsigned p99_iterator_signal(p99_iterator volatile* p00_i) {
117  return p99_futex_add(&p00_i->p00_seen, 1u, 0u, UINT_MAX, 0u, P99_FUTEX_MAX_WAITERS);
118 }
119 
120 
122 
123 struct p99_event {
124  p99_iterator p00_it;
125  unsigned p00_n;
126  void ** p00_event;
127 };
128 
135 p99_event* p99_event_init(p99_event* p00_e, unsigned p00_n) {
136  if (p00_e) {
137  (*p00_e) = (p99_event) {
138  .p00_n = p00_n,
139  .p00_event = P99_MEMZERO(void_ptr, P99_MALLOC(void_ptr[p00_n]), p00_n),
140  };
141  p99_iterator_init(&p00_e->p00_it);
142  }
143  return p00_e;
144 }
145 
152  if (p00_e) {
153  free(p00_e->p00_event);
154  p99_iterator_destroy(&p00_e->p00_it);
155  }
156 }
157 
167 P00_FUTEX_INLINE(p99_event_next)
168 void* p99_event_next(p99_event volatile* p00_e) {
169  P99_FPRINTF(stderr, "next event on %s\n", (void*)p00_e);
170  unsigned p00_pos = p99_iterator_next(&p00_e->p00_it);
171  void* p00_ret = 0;
172  if (p00_pos < p00_e->p00_n)
173  while (!(p00_ret = p00_e->p00_event[p00_pos]));
174  P99_FPRINTF(stderr, "next event on %s, returns %s pos %s\n", (void*)p00_e, p00_ret, p00_pos);
175  return p00_ret;
176 }
177 
185 void p99_event_signal(p99_event volatile* p00_e, void * p00_w) {
186  if (p00_e) {
187  unsigned p00_ret = p99_iterator_signal(&p00_e->p00_it);
188  p00_e->p00_event[p00_ret] = p00_w;
189  }
190 }
191 
192 
198 #endif
void
void void
Definition: p99_bitset.h:84
p99_futex.h
P99_FPRINTF
#define P99_FPRINTF(F, FORMAT,...)
Definition: p99_generic.h:1439
p99_event::p99_event_init
p99_event * p99_event_init(p99_event *p00_e, unsigned p00_n)
Initialize an event.
Definition: p99_iterator.h:135
P99_MEMZERO
#define P99_MEMZERO(T, TA, N)
A type oriented replacement for memset with argument 0.
Definition: p99_new.h:164
p99_futex::p99_futex_destroy
void p99_futex_destroy(p99_futex *p00_c)
Destroy an p99_futex object.
p99_futex
A counter similar to a conditional variable that allows atomic increment and decrement and to wait fo...
Definition: p99_futex.h:163
p99_event
struct p99_event p99_event
Definition: p99_iterator.h:121
p99_iterator
Iterate over a series events that are signaled by other threads.
Definition: p99_iterator.h:55
p99_event::p99_event_destroy
void p99_event_destroy(p99_event *p00_e)
destroy an event
Definition: p99_iterator.h:151
p99_iterator::p99_iterator_init
p99_iterator * p99_iterator_init(p99_iterator *p00_i)
Initialize an iterator.
Definition: p99_iterator.h:66
p99_iterator::p99_iterator_destroy
void p99_iterator_destroy(p99_iterator *p00_i)
destroy a iterator
Definition: p99_iterator.h:79
p99_iterator::p99_iterator_signal
unsigned p99_iterator_signal(p99_iterator volatile *p00_i)
Signal an event.
Definition: p99_iterator.h:116
p99_event
Definition: p99_iterator.h:123
p99_inline
#define p99_inline
Try to force a function always to be inlined.
Definition: p99_compiler.h:496
p99_futex::P99_FUTEX_COMPARE_EXCHANGE
#define P99_FUTEX_COMPARE_EXCHANGE(FUTEX, ACT, EXPECTED, DESIRED, WAKEMIN, WAKEMAX)
a catch all macro to operate on p99_futex
Definition: p99_futex.h:563
unsigned
void unsigned(void)
p99_event::p99_event_next
void * p99_event_next(p99_event volatile *p00_e)
Block until an event has been signaled that has not yet been accounted for.
Definition: p99_iterator.h:168
P99_DEFARG_DOCU
#define P99_DEFARG_DOCU(NAME)
Provide a documentation section to a function defined with P99_CALL_DEFARG.
Definition: p99_defarg.h:318
P99_DECLARE_STRUCT
#define P99_DECLARE_STRUCT(NAME)
forward declaration of a struct NAME
Definition: p99_type.h:59
p99_event::p99_event_signal
void p99_event_signal(p99_event volatile *p00_e, void *p00_w)
Signal the event. p00_w.
Definition: p99_iterator.h:185
p99_iterator::p99_iterator_next
unsigned p99_iterator_next(p99_iterator volatile *p00_i)
Block until an event has been signaled that has not yet been accounted for.
Definition: p99_iterator.h:95
P99_MALLOC
#define P99_MALLOC(X)
A type oriented malloc wrapper.
Definition: p99_new.h:190
p99_futex::p99_futex_add
unsigned p99_futex_add(p99_futex volatile *p00_fut, unsigned p00_hmuch, unsigned p00_cstart, unsigned p00_clen, unsigned p00_wmin, unsigned p00_wmax)
increment the counter of p00_fut atomically by p00_hmuch.
p99_futex::P99_FUTEX_MAX_WAITERS
#define P99_FUTEX_MAX_WAITERS
the maximum number of waiters that an p99_futex may have
Definition: p99_futex.h:178
p99_futex::p99_futex_init
p99_futex * p99_futex_init(p99_futex *p00_c, unsigned p00_ini)
Initialize an p99_futex object.
void_ptr
void * void_ptr
a pointer to void
Definition: p99_typenames.h:70