• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pybricks / pybricks-micropython / 6675885095

28 Oct 2023 08:38AM UTC coverage: 56.053% (+10.0%) from 46.074%
6675885095

push

github

laurensvalk
pybricks.hubs.MoveHub: Use standard hub init.

The Move Hub cannot have true vector axes, but we can still use this API to initialize the hub using numeric indices.

This ensures we can use the custom orientation not just in tilt, but also in acceleration like we do on other hubs.

3616 of 6451 relevant lines covered (56.05%)

20895680.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.81
/lib/contiki-core/sys/process.c
1
// SPDX-License-Identifier: BSD-3-Clause
2
/*
3
 * Copyright (c) 2005, Swedish Institute of Computer Science
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the Institute nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 * This file is part of the Contiki operating system.
31
 *
32
 */
33

34
/**
35
 * \addtogroup process
36
 * @{
37
 */
38

39
/**
40
 * \file
41
 *         Implementation of the Contiki process kernel.
42
 * \author
43
 *         Adam Dunkels <adam@sics.se>
44
 *
45
 */
46

47
#include <stdio.h>
48

49
#include "sys/process.h"
50
#include "sys/arg.h"
51

52
/*
53
 * Pointer to the currently running process structure.
54
 */
55
struct process *process_list = NULL;
56
struct process *process_current = NULL;
57

58
static process_event_t lastevent;
59

60
/*
61
 * Structure used for keeping the queue of active events.
62
 */
63
struct event_data {
64
  process_event_t ev;
65
  process_data_t data;
66
  struct process *p;
67
};
68

69
static process_num_events_t nevents, fevent;
70
static struct event_data events[PROCESS_CONF_NUMEVENTS];
71

72
#if PROCESS_CONF_STATS
73
process_num_events_t process_maxevents;
74
#endif
75

76
static volatile unsigned char poll_requested;
77

78
#define PROCESS_STATE_NONE        0
79
#define PROCESS_STATE_RUNNING     1
80
#define PROCESS_STATE_CALLED      2
81

82
static void call_process(struct process *p, process_event_t ev, process_data_t data);
83

84
#define DEBUG 0
85
#if DEBUG
86
#include <stdio.h>
87
#define PRINTF(...) printf(__VA_ARGS__)
88
#else
89
#define PRINTF(...)
90
#endif
91

92
/*---------------------------------------------------------------------------*/
93
process_event_t
94
process_alloc_event(void)
×
95
{
96
  return lastevent++;
×
97
}
98
/*---------------------------------------------------------------------------*/
99
void
100
process_start(struct process *p)
84✔
101
{
102
  struct process *q;
84✔
103

104
  /* First make sure that we don't try to start a process that is
105
     already running. */
106
  for(q = process_list; q != p && q != NULL; q = q->next);
210✔
107

108
  /* If we found the process on the process list, we bail out. */
109
  if(q == p) {
84✔
110
    return;
111
  }
112
  /* Put on the procs list.*/
113
  p->next = process_list;
84✔
114
  process_list = p;
84✔
115
  p->state = PROCESS_STATE_RUNNING;
84✔
116
  PT_INIT(&p->pt);
84✔
117

118
  PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p));
84✔
119

120
  /* Post a synchronous initialization event to the process. */
121
  process_post_synch(p, PROCESS_EVENT_INIT, NULL);
84✔
122
}
123
/*---------------------------------------------------------------------------*/
124
static void
125
exit_process(struct process *p, struct process *fromprocess)
×
126
{
127
  register struct process *q;
×
128
  struct process *old_current = process_current;
×
129

130
  PRINTF("process: exit_process '%s'\n", PROCESS_NAME_STRING(p));
×
131

132
  /* Make sure the process is in the process list before we try to
133
     exit it. */
134
  for(q = process_list; q != p && q != NULL; q = q->next);
×
135
  if(q == NULL) {
×
136
    return;
137
  }
138

139
  if(process_is_running(p)) {
×
140
    /* Process was running */
141
    p->state = PROCESS_STATE_NONE;
×
142

143
    /*
144
     * Post a synchronous event to all processes to inform them that
145
     * this process is about to exit. This will allow services to
146
     * deallocate state associated with this process.
147
     */
148
    for(q = process_list; q != NULL; q = q->next) {
×
149
      if(p != q) {
×
150
        call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p);
×
151
      }
152
    }
153

154
    if(p->thread != NULL && p != fromprocess) {
×
155
      /* Post the exit event to the process that is about to exit. */
156
      process_current = p;
×
157
      p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL);
×
158
    }
159
  }
160

161
  if(p == process_list) {
×
162
    process_list = process_list->next;
×
163
  } else {
164
    for(q = process_list; q != NULL; q = q->next) {
×
165
      if(q->next == p) {
×
166
        q->next = p->next;
×
167
        break;
×
168
      }
169
    }
170
  }
171

172
  process_current = old_current;
×
173
}
174
/*---------------------------------------------------------------------------*/
175
static void
176
call_process(struct process *p, process_event_t ev, process_data_t data)
54,819✔
177
{
178
  int ret;
54,819✔
179

180
#if DEBUG
181
  if(p->state == PROCESS_STATE_CALLED) {
182
    printf("process: process '%s' called again with event 0x%02X\n", PROCESS_NAME_STRING(p), ev);
183
  }
184
#endif /* DEBUG */
185

186
  if((p->state & PROCESS_STATE_RUNNING) &&
54,819✔
187
     p->thread != NULL) {
54,819✔
188
    PRINTF("process: calling process '%s' with event 0x%02X\n", PROCESS_NAME_STRING(p), ev);
54,819✔
189
    process_current = p;
54,819✔
190
    p->state = PROCESS_STATE_CALLED;
54,819✔
191
    ret = p->thread(&p->pt, ev, data);
54,819✔
192
    if(ret == PT_EXITED ||
54,819✔
193
       ret == PT_ENDED ||
54,819✔
194
       ev == PROCESS_EVENT_EXIT) {
195
      exit_process(p, p);
×
196
    } else {
197
      p->state = PROCESS_STATE_RUNNING;
54,819✔
198
    }
199
  }
200
}
54,819✔
201
/*---------------------------------------------------------------------------*/
202
void
203
process_exit(struct process *p)
×
204
{
205
  exit_process(p, PROCESS_CURRENT());
×
206
}
×
207
/*---------------------------------------------------------------------------*/
208
void
209
process_init(void)
21✔
210
{
211
  lastevent = PROCESS_EVENT_MAX;
21✔
212

213
  nevents = fevent = 0;
21✔
214
#if PROCESS_CONF_STATS
215
  process_maxevents = 0;
216
#endif /* PROCESS_CONF_STATS */
217

218
  process_current = process_list = NULL;
21✔
219
}
21✔
220
/*---------------------------------------------------------------------------*/
221
/*
222
 * Call each process' poll handler.
223
 */
224
/*---------------------------------------------------------------------------*/
225
static void
226
do_poll(void)
35,277✔
227
{
228
  struct process *p;
35,277✔
229

230
  poll_requested = 0;
35,277✔
231
  /* Call the processes that needs to be polled. */
232
  for(p = process_list; p != NULL; p = p->next) {
176,385✔
233
    if(p->needspoll) {
141,108✔
234
      p->state = PROCESS_STATE_RUNNING;
35,277✔
235
      p->needspoll = 0;
35,277✔
236
      call_process(p, PROCESS_EVENT_POLL, NULL);
35,277✔
237
    }
238
  }
239
}
35,277✔
240
/*---------------------------------------------------------------------------*/
241
/*
242
 * Process the next event in the event queue and deliver it to
243
 * listening processes.
244
 */
245
/*---------------------------------------------------------------------------*/
246
static void
247
do_event(void)
34,165,259✔
248
{
249
  process_event_t ev;
34,165,259✔
250
  process_data_t data;
34,165,259✔
251
  struct process *receiver;
34,165,259✔
252
  struct process *p;
34,165,259✔
253

254
  /*
255
   * If there are any events in the queue, take the first one and walk
256
   * through the list of processes to see if the event should be
257
   * delivered to any of them. If so, we call the event handler
258
   * function for the process. We only process one event at a time and
259
   * call the poll handlers inbetween.
260
   */
261

262
  if(nevents > 0) {
34,165,259✔
263

264
    /* There are events that we should deliver. */
265
    ev = events[fevent].ev;
19,395✔
266

267
    data = events[fevent].data;
19,395✔
268
    receiver = events[fevent].p;
19,395✔
269

270
    /* Since we have seen the new event, we move pointer upwards
271
       and decrease the number of events. */
272
    fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS;
19,395✔
273
    --nevents;
19,395✔
274

275
    /* If this is a broadcast event, we deliver it to all events, in
276
       order of their priority. */
277
    if(receiver == PROCESS_BROADCAST) {
19,395✔
278
      for(p = process_list; p != NULL; p = p->next) {
105✔
279

280
        /* If we have been requested to poll a process, we do this in
281
           between processing the broadcast event. */
282
        if(poll_requested) {
84✔
283
          do_poll();
×
284
        }
285
        call_process(p, ev, data);
84✔
286
      }
287
    } else {
288
      /* This is not a broadcast event, so we deliver it to the
289
         specified process. */
290
      /* If the event was an INIT event, we should also update the
291
         state of the process. */
292
      if(ev == PROCESS_EVENT_INIT) {
19,374✔
293
        receiver->state = PROCESS_STATE_RUNNING;
×
294
      }
295

296
      /* Make sure that the process actually is running. */
297
      call_process(receiver, ev, data);
19,374✔
298
    }
299
  }
300
}
34,165,259✔
301
/*---------------------------------------------------------------------------*/
302
int
303
process_run(void)
34,165,259✔
304
{
305
  /* Process poll events. */
306
  if(poll_requested) {
34,165,259✔
307
    do_poll();
35,277✔
308
  }
309

310
  /* Process one event from the queue */
311
  do_event();
34,165,259✔
312

313
  return nevents + poll_requested;
34,165,259✔
314
}
315
/*---------------------------------------------------------------------------*/
316
int
317
process_nevents(void)
96,069✔
318
{
319
  return nevents + poll_requested;
96,069✔
320
}
321
/*---------------------------------------------------------------------------*/
322
int
323
process_post(struct process *p, process_event_t ev, process_data_t data)
19,395✔
324
{
325
  process_num_events_t snum;
19,395✔
326

327
  if(PROCESS_CURRENT() == NULL) {
19,395✔
328
    PRINTF("process_post: NULL process posts event 0x%02X to process '%s', nevents %d\n",
329
           ev,PROCESS_NAME_STRING(p), nevents);
330
  } else {
331
    PRINTF("process_post: Process '%s' posts event 0x%02X to process '%s', nevents %d\n",
332
           PROCESS_NAME_STRING(PROCESS_CURRENT()), ev,
333
           p == PROCESS_BROADCAST? "<broadcast>": PROCESS_NAME_STRING(p), nevents);
19,395✔
334
  }
335

336
  if(nevents == PROCESS_CONF_NUMEVENTS) {
19,395✔
337
#if DEBUG
338
    if(p == PROCESS_BROADCAST) {
339
      printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current));
340
    } else {
341
      printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current));
342
    }
343
#endif /* DEBUG */
344
    return PROCESS_ERR_FULL;
345
  }
346

347
  snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS;
19,395✔
348
  events[snum].ev = ev;
19,395✔
349
  events[snum].data = data;
19,395✔
350
  events[snum].p = p;
19,395✔
351
  ++nevents;
19,395✔
352

353
#if PROCESS_CONF_STATS
354
  if(nevents > process_maxevents) {
355
    process_maxevents = nevents;
356
  }
357
#endif /* PROCESS_CONF_STATS */
358

359
  return PROCESS_ERR_OK;
19,395✔
360
}
361
/*---------------------------------------------------------------------------*/
362
void
363
process_post_synch(struct process *p, process_event_t ev, process_data_t data)
84✔
364
{
365
  struct process *caller = process_current;
84✔
366

367
  call_process(p, ev, data);
84✔
368
  process_current = caller;
84✔
369
}
84✔
370
/*---------------------------------------------------------------------------*/
371
void
372
process_poll(struct process *p)
35,343✔
373
{
374
  if(p != NULL) {
35,343✔
375
    if(p->state == PROCESS_STATE_RUNNING ||
35,343✔
376
       p->state == PROCESS_STATE_CALLED) {
377
      p->needspoll = 1;
35,343✔
378
      poll_requested = 1;
35,343✔
379
    }
380
  }
381
}
35,343✔
382
/*---------------------------------------------------------------------------*/
383
int
384
process_is_running(struct process *p)
×
385
{
386
  return p->state != PROCESS_STATE_NONE;
×
387
}
388
/*---------------------------------------------------------------------------*/
389
/** @} */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc