source: rtems/bsps/shared/irq/irq-server.c @ 739e3d0

5
Last change on this file since 739e3d0 was 739e3d0, checked in by Gedare Bloom <gedare@…>, on 01/03/20 at 18:33:02

bsps/irq: fix resource leak in irq-server.c

Resource leak identified by Coverity (CID 1456675). The value
of instances is leaked in case some but not all irq servers are
created. It should be stored in bsp_interrupt_server_instances.

  • Property mode set to 100644
File size: 19.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_interrupt
5 *
6 * @brief Generic BSP interrupt server implementation.
7 */
8
9/*
10 * Copyright (c) 2009, 2019 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <stdlib.h>
24
25#include <rtems.h>
26#include <rtems/chain.h>
27#include <rtems/score/assert.h>
28
29#include <bsp/irq-generic.h>
30
31#define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
32
33typedef struct {
34  RTEMS_INTERRUPT_LOCK_MEMBER(lock);
35  rtems_chain_control entries;
36  rtems_id server;
37  unsigned errors;
38} bsp_interrupt_server_context;
39
40#if defined(RTEMS_SMP)
41static bsp_interrupt_server_context *bsp_interrupt_server_instances;
42#else
43static bsp_interrupt_server_context bsp_interrupt_server_instance;
44#endif
45
46static bsp_interrupt_server_context *bsp_interrupt_server_get_context(
47  uint32_t server_index,
48  rtems_status_code *sc
49)
50{
51#if defined(RTEMS_SMP)
52  if (bsp_interrupt_server_instances == NULL) {
53    *sc = RTEMS_INCORRECT_STATE;
54    return NULL;
55  }
56#else
57  if (bsp_interrupt_server_instance.server == RTEMS_ID_NONE) {
58    *sc = RTEMS_INCORRECT_STATE;
59    return NULL;
60  }
61#endif
62
63  if (server_index >= rtems_scheduler_get_processor_maximum()) {
64    *sc = RTEMS_INVALID_ID;
65    return NULL;
66  }
67
68  *sc = RTEMS_SUCCESSFUL;
69#if defined(RTEMS_SMP)
70  return &bsp_interrupt_server_instances[server_index];
71#else
72  return &bsp_interrupt_server_instance;
73#endif
74}
75
76static void bsp_interrupt_server_trigger(void *arg)
77{
78  rtems_interrupt_lock_context lock_context;
79  rtems_interrupt_server_entry *e = arg;
80  bsp_interrupt_server_context *s = e->server;
81
82  if (bsp_interrupt_is_valid_vector(e->vector)) {
83    bsp_interrupt_vector_disable(e->vector);
84  }
85
86  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
87
88  if (rtems_chain_is_node_off_chain(&e->node)) {
89    rtems_chain_append_unprotected(&s->entries, &e->node);
90  } else {
91    ++s->errors;
92  }
93
94  rtems_interrupt_lock_release(&s->lock, &lock_context);
95
96  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER);
97}
98
99typedef struct {
100  rtems_interrupt_server_entry *entry;
101  rtems_option *options;
102} bsp_interrupt_server_iterate_entry;
103
104static void bsp_interrupt_server_per_handler_routine(
105  void *iterate_arg,
106  const char *info,
107  rtems_option options,
108  rtems_interrupt_handler handler,
109  void *handler_arg
110)
111{
112  if (handler == bsp_interrupt_server_trigger) {
113    bsp_interrupt_server_iterate_entry *ie = iterate_arg;
114
115    ie->entry = handler_arg;
116    *ie->options = options;
117  }
118}
119
120static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
121  rtems_vector_number vector,
122  rtems_option *trigger_options
123)
124{
125  bsp_interrupt_server_iterate_entry ie = {
126    .entry = NULL,
127    .options = trigger_options
128  };
129
130  rtems_interrupt_handler_iterate(
131    vector,
132    bsp_interrupt_server_per_handler_routine,
133    &ie
134  );
135
136  return ie.entry;
137}
138
139typedef struct {
140  bsp_interrupt_server_context *server;
141  rtems_vector_number vector;
142  rtems_option options;
143  rtems_interrupt_handler handler;
144  void *arg;
145  rtems_id task;
146  rtems_status_code sc;
147} bsp_interrupt_server_helper_data;
148
149static void bsp_interrupt_server_install_helper(void *arg)
150{
151  bsp_interrupt_server_helper_data *hd = arg;
152  rtems_status_code sc;
153  rtems_interrupt_server_entry *e;
154  rtems_interrupt_server_action *a;
155  rtems_option trigger_options;
156
157  a = calloc(1, sizeof(*a));
158  if (a == NULL) {
159    hd->sc = RTEMS_NO_MEMORY;
160    rtems_event_transient_send(hd->task);
161    return;
162  }
163
164  a->handler = hd->handler;
165  a->arg = hd->arg;
166
167  bsp_interrupt_lock();
168
169  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
170  if (e == NULL) {
171    e = calloc(1, sizeof(*e));
172    if (e != NULL) {
173      e->server = hd->server;
174      e->vector = hd->vector;
175      e->actions = a;
176
177      sc = rtems_interrupt_handler_install(
178        hd->vector,
179        "IRQS",
180        hd->options & RTEMS_INTERRUPT_UNIQUE,
181        bsp_interrupt_server_trigger,
182        e
183      );
184      if (sc != RTEMS_SUCCESSFUL) {
185        free(e);
186      }
187    } else {
188      sc = RTEMS_NO_MEMORY;
189    }
190#if defined(RTEMS_SMP)
191  } else if (e->server != hd->server) {
192    sc = RTEMS_RESOURCE_IN_USE;
193#endif
194  } else if (
195    RTEMS_INTERRUPT_IS_UNIQUE(hd->options)
196      || RTEMS_INTERRUPT_IS_UNIQUE(trigger_options)
197  ) {
198    sc = RTEMS_RESOURCE_IN_USE;
199  } else {
200    rtems_interrupt_server_action **link = &e->actions;
201    rtems_interrupt_server_action *c;
202
203    sc = RTEMS_SUCCESSFUL;
204
205    while ((c = *link) != NULL) {
206      if (c->handler == hd->handler && c->arg == hd->arg) {
207        sc = RTEMS_TOO_MANY;
208        break;
209      }
210
211      link = &c->next;
212    }
213
214    if (sc == RTEMS_SUCCESSFUL) {
215      *link = a;
216    }
217  }
218
219  bsp_interrupt_unlock();
220
221  if (sc != RTEMS_SUCCESSFUL) {
222    free(a);
223  }
224
225  hd->sc = sc;
226  rtems_event_transient_send(hd->task);
227}
228
229static void bsp_interrupt_server_remove_helper(void *arg)
230{
231  bsp_interrupt_server_helper_data *hd = arg;
232  rtems_status_code sc;
233  rtems_interrupt_server_entry *e;
234  rtems_option trigger_options;
235
236  bsp_interrupt_lock();
237
238  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
239  if (e != NULL) {
240    rtems_interrupt_server_action **link = &e->actions;
241    rtems_interrupt_server_action *c;
242
243    while ((c = *link) != NULL) {
244      if (c->handler == hd->handler && c->arg == hd->arg) {
245        break;
246      }
247
248      link = &c->next;
249    }
250
251    if (c != NULL) {
252      bool remove_last = e->actions->next == NULL;
253
254      if (remove_last) {
255        rtems_interrupt_handler_remove(
256          hd->vector,
257          bsp_interrupt_server_trigger,
258          e
259        );
260      }
261
262      *link = c->next;
263      free(c);
264
265      if (remove_last) {
266        free(e);
267      }
268
269      sc = RTEMS_SUCCESSFUL;
270    } else {
271      sc = RTEMS_UNSATISFIED;
272    }
273  } else {
274    sc = RTEMS_INVALID_ID;
275  }
276
277  bsp_interrupt_unlock();
278
279  hd->sc = sc;
280  rtems_event_transient_send(hd->task);
281}
282
283static rtems_status_code bsp_interrupt_server_call_helper(
284  bsp_interrupt_server_context *s,
285  rtems_vector_number vector,
286  rtems_option options,
287  rtems_interrupt_handler handler,
288  void *arg,
289  void (*helper)(void *)
290)
291{
292  bsp_interrupt_server_helper_data hd = {
293    .server = s,
294    .vector = vector,
295    .options = options,
296    .handler = handler,
297    .arg = arg,
298    .task = rtems_task_self()
299  };
300  rtems_interrupt_server_action a = {
301    .handler = helper,
302    .arg = &hd
303  };
304  rtems_interrupt_server_entry e = {
305    .server = s,
306    .vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
307    .actions = &a
308  };
309
310  bsp_interrupt_server_trigger(&e);
311  rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
312
313  return hd.sc;
314}
315
316static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
317  bsp_interrupt_server_context *s
318)
319{
320  rtems_interrupt_lock_context lock_context;
321  rtems_interrupt_server_entry *e;
322
323  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
324
325  if (!rtems_chain_is_empty(&s->entries)) {
326    e = (rtems_interrupt_server_entry *)
327      rtems_chain_get_first_unprotected(&s->entries);
328    rtems_chain_set_off_chain(&e->node);
329  } else {
330    e = NULL;
331  }
332
333  rtems_interrupt_lock_release(&s->lock, &lock_context);
334
335  return e;
336}
337
338static void bsp_interrupt_server_task(rtems_task_argument arg)
339{
340  bsp_interrupt_server_context *s = (bsp_interrupt_server_context *) arg;
341
342  while (true) {
343    rtems_event_set events;
344    rtems_interrupt_server_entry *e;
345
346    rtems_event_system_receive(
347      RTEMS_EVENT_SYSTEM_SERVER,
348      RTEMS_EVENT_ALL | RTEMS_WAIT,
349      RTEMS_NO_TIMEOUT,
350      &events
351    );
352
353    while ((e = bsp_interrupt_server_get_entry(s)) != NULL) {
354      rtems_interrupt_server_action *action = e->actions;
355      rtems_vector_number vector = e->vector;
356
357      do {
358        rtems_interrupt_server_action *current = action;
359        action = action->next;
360        (*current->handler)(current->arg);
361      } while (action != NULL);
362
363      if (bsp_interrupt_is_valid_vector(vector)) {
364        bsp_interrupt_vector_enable(vector);
365      }
366    }
367  }
368}
369
370rtems_status_code rtems_interrupt_server_handler_install(
371  uint32_t server_index,
372  rtems_vector_number vector,
373  const char *info,
374  rtems_option options,
375  rtems_interrupt_handler handler,
376  void *arg
377)
378{
379  rtems_status_code sc;
380  bsp_interrupt_server_context *s;
381
382  s = bsp_interrupt_server_get_context(server_index, &sc);
383  if (s == NULL) {
384    return sc;
385  }
386
387  return bsp_interrupt_server_call_helper(
388    s,
389    vector,
390    options,
391    handler,
392    arg,
393    bsp_interrupt_server_install_helper
394  );
395}
396
397rtems_status_code rtems_interrupt_server_handler_remove(
398  uint32_t server_index,
399  rtems_vector_number vector,
400  rtems_interrupt_handler handler,
401  void *arg
402)
403{
404  rtems_status_code sc;
405  bsp_interrupt_server_context *s;
406
407  s = bsp_interrupt_server_get_context(server_index, &sc);
408  if (s == NULL) {
409    return sc;
410  }
411
412  return bsp_interrupt_server_call_helper(
413    s,
414    vector,
415    0,
416    handler,
417    arg,
418    bsp_interrupt_server_remove_helper
419  );
420}
421
422typedef struct {
423  rtems_interrupt_per_handler_routine routine;
424  void *arg;
425} bsp_interrupt_server_handler_iterate_helper_data;
426
427static void bsp_interrupt_server_handler_iterate_helper(void *arg)
428{
429  bsp_interrupt_server_helper_data *hd = arg;
430  bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
431  rtems_status_code sc;
432  rtems_interrupt_server_entry *e;
433  rtems_option trigger_options;
434
435  bsp_interrupt_lock();
436
437  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
438  if (e != NULL) {
439    rtems_interrupt_server_action **link = &e->actions;
440    rtems_interrupt_server_action *c;
441
442    while ((c = *link) != NULL) {
443      (*hihd->routine)(hihd->arg, NULL, trigger_options, c->handler, c->arg);
444      link = &c->next;
445    }
446
447    sc = RTEMS_SUCCESSFUL;
448  } else {
449    sc = RTEMS_UNSATISFIED;
450  }
451
452  bsp_interrupt_unlock();
453
454  hd->sc = sc;
455  rtems_event_transient_send(hd->task);
456}
457
458rtems_status_code rtems_interrupt_server_handler_iterate(
459  uint32_t server_index,
460  rtems_vector_number vector,
461  rtems_interrupt_per_handler_routine routine,
462  void *arg
463)
464{
465  rtems_status_code sc;
466  bsp_interrupt_server_handler_iterate_helper_data hihd;
467  bsp_interrupt_server_context *s;
468
469  s = bsp_interrupt_server_get_context(server_index, &sc);
470  if (s == NULL) {
471    return sc;
472  }
473
474  if (!bsp_interrupt_is_valid_vector(vector)) {
475    return RTEMS_INVALID_ID;
476  }
477
478  hihd.routine = routine;
479  hihd.arg = arg;
480  return bsp_interrupt_server_call_helper(
481    s,
482    vector,
483    0,
484    NULL,
485    &hihd,
486    bsp_interrupt_server_handler_iterate_helper
487  );
488}
489
490rtems_status_code rtems_interrupt_server_initialize(
491  rtems_task_priority priority,
492  size_t stack_size,
493  rtems_mode modes,
494  rtems_attribute attributes,
495  uint32_t *server_count
496)
497{
498  uint32_t cpu_index;
499  uint32_t cpu_count;
500  uint32_t dummy;
501  bsp_interrupt_server_context *instances;
502
503  if (server_count == NULL) {
504    server_count = &dummy;
505  }
506
507  cpu_count = rtems_scheduler_get_processor_maximum();
508
509#if defined(RTEMS_SMP)
510  instances = calloc(cpu_count, sizeof(*instances));
511  if (instances == NULL) {
512    return RTEMS_NO_MEMORY;
513  }
514#else
515  instances = &bsp_interrupt_server_instance;
516#endif
517
518  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
519    bsp_interrupt_server_context *s = &instances[cpu_index];
520    rtems_status_code sc;
521#if defined(RTEMS_SMP)
522    rtems_id scheduler;
523    cpu_set_t cpu;
524#endif
525
526    rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
527    rtems_chain_initialize_empty(&s->entries);
528
529    sc = rtems_task_create(
530      rtems_build_name('I', 'R', 'Q', 'S'),
531      priority,
532      stack_size,
533      modes,
534      attributes,
535      &s->server
536    );
537    if (sc != RTEMS_SUCCESSFUL) {
538      *server_count = cpu_index;
539
540#if defined(RTEMS_SMP)
541      if (cpu_index > 0) {
542        bsp_interrupt_server_instances = instances;
543        return RTEMS_SUCCESSFUL;
544      }
545
546      free(instances);
547#endif
548
549      return RTEMS_TOO_MANY;
550    }
551
552#if defined(RTEMS_SMP)
553    sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
554    if (sc != RTEMS_SUCCESSFUL) {
555      /* Do not start an interrupt server on a processor without a scheduler */
556      continue;
557    }
558
559    sc = rtems_task_set_scheduler(s->server, scheduler, priority);
560    _Assert(sc == RTEMS_SUCCESSFUL);
561
562    /* Set the task to processor affinity on a best-effort basis */
563    CPU_ZERO(&cpu);
564    CPU_SET(cpu_index, &cpu);
565    (void) rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
566#endif
567
568    sc = rtems_task_start(
569      s->server,
570      bsp_interrupt_server_task,
571      (rtems_task_argument) s
572    );
573    _Assert(sc == RTEMS_SUCCESSFUL);
574  }
575
576#if defined(RTEMS_SMP)
577  bsp_interrupt_server_instances = instances;
578#endif
579  *server_count = cpu_index;
580
581  return RTEMS_SUCCESSFUL;
582}
583
584static void bsp_interrupt_server_entry_initialize(
585  rtems_interrupt_server_entry *entry,
586  bsp_interrupt_server_context *s
587)
588{
589  rtems_chain_set_off_chain(&entry->node);
590  entry->server = s;
591  entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
592  entry->actions = NULL;
593}
594
595static void bsp_interrupt_server_action_prepend(
596  rtems_interrupt_server_entry  *entry,
597  rtems_interrupt_server_action *action,
598  rtems_interrupt_handler        handler,
599  void                          *arg
600)
601{
602  action->handler = handler;
603  action->arg = arg;
604  action->next = entry->actions;
605  entry->actions = action;
606}
607
608rtems_status_code rtems_interrupt_server_entry_initialize(
609  uint32_t                      server_index,
610  rtems_interrupt_server_entry *entry
611)
612{
613  rtems_status_code sc;
614  bsp_interrupt_server_context *s;
615
616  s = bsp_interrupt_server_get_context(server_index, &sc);
617  if (s == NULL) {
618    return sc;
619  }
620
621  bsp_interrupt_server_entry_initialize(entry, s);
622  return RTEMS_SUCCESSFUL;
623}
624
625void rtems_interrupt_server_action_prepend(
626  rtems_interrupt_server_entry  *entry,
627  rtems_interrupt_server_action *action,
628  rtems_interrupt_handler        handler,
629  void                          *arg
630)
631{
632  bsp_interrupt_server_action_prepend(entry, action, handler, arg);
633}
634
635void rtems_interrupt_server_entry_submit(
636  rtems_interrupt_server_entry *entry
637)
638{
639  bsp_interrupt_server_trigger(entry);
640}
641
642rtems_status_code rtems_interrupt_server_entry_move(
643  rtems_interrupt_server_entry *entry,
644  uint32_t                      destination_server_index
645)
646{
647  rtems_status_code sc;
648  bsp_interrupt_server_context *s;
649
650  s = bsp_interrupt_server_get_context(destination_server_index, &sc);
651  if (s == NULL) {
652    return sc;
653  }
654
655  entry->server = s;
656  return RTEMS_SUCCESSFUL;
657}
658
659static void bsp_interrupt_server_entry_synchronize_helper(void *arg)
660{
661  bsp_interrupt_server_helper_data *hd = arg;
662
663  rtems_event_transient_send(hd->task);
664}
665
666void rtems_interrupt_server_entry_destroy(
667  rtems_interrupt_server_entry *entry
668)
669{
670  bsp_interrupt_server_context *s;
671  rtems_interrupt_lock_context lock_context;
672
673  s = entry->server;
674  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
675
676  if (!rtems_chain_is_node_off_chain(&entry->node)) {
677    rtems_chain_extract_unprotected(&entry->node);
678    rtems_chain_set_off_chain(&entry->node);
679  }
680
681  rtems_interrupt_lock_release(&s->lock, &lock_context);
682
683  bsp_interrupt_server_call_helper(
684    s,
685    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
686    0,
687    NULL,
688    NULL,
689    bsp_interrupt_server_entry_synchronize_helper
690  );
691}
692
693rtems_status_code rtems_interrupt_server_request_initialize(
694  uint32_t                        server_index,
695  rtems_interrupt_server_request *request,
696  rtems_interrupt_handler         handler,
697  void                           *arg
698)
699{
700  rtems_status_code sc;
701  bsp_interrupt_server_context *s;
702
703  s = bsp_interrupt_server_get_context(server_index, &sc);
704  if (s == NULL) {
705    return sc;
706  }
707
708  bsp_interrupt_server_entry_initialize(&request->entry, s);
709  bsp_interrupt_server_action_prepend(
710    &request->entry,
711    &request->action,
712    handler,
713    arg
714  );
715  return RTEMS_SUCCESSFUL;
716}
717
718static void bsp_interrupt_server_handler_move_helper(void *arg)
719{
720  bsp_interrupt_server_helper_data *hd = arg;
721  bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
722  rtems_interrupt_server_entry *e;
723  rtems_option trigger_options;
724
725  bsp_interrupt_lock();
726
727  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
728  if (e != NULL) {
729    rtems_interrupt_lock_context lock_context;
730    bsp_interrupt_server_context *src = e->server;
731    bsp_interrupt_server_context *dst = hihd->arg;
732    bool pending;
733
734    /* The source server is only used in SMP configurations for the lock */
735    (void) src;
736
737    rtems_interrupt_lock_acquire(&src->lock, &lock_context);
738
739    pending = !rtems_chain_is_node_off_chain(&e->node);
740    if (pending) {
741      rtems_chain_extract_unprotected(&e->node);
742      rtems_chain_set_off_chain(&e->node);
743    }
744
745    rtems_interrupt_lock_release(&src->lock, &lock_context);
746
747    e->server = dst;
748
749    if (pending) {
750      bsp_interrupt_server_trigger(e);
751    }
752  }
753
754  bsp_interrupt_unlock();
755
756  rtems_event_transient_send(hd->task);
757}
758
759rtems_status_code rtems_interrupt_server_move(
760  uint32_t source_server_index,
761  rtems_vector_number vector,
762  uint32_t destination_server_index
763)
764{
765  rtems_status_code sc;
766  bsp_interrupt_server_context *src;
767  bsp_interrupt_server_context *dst;
768  bsp_interrupt_server_handler_iterate_helper_data hihd;
769
770  src = bsp_interrupt_server_get_context(source_server_index, &sc);
771  if (src == NULL) {
772    return sc;
773  }
774
775  dst = bsp_interrupt_server_get_context(destination_server_index, &sc);
776  if (dst == NULL) {
777    return sc;
778  }
779
780  if (!bsp_interrupt_is_valid_vector(vector)) {
781    return RTEMS_INVALID_ID;
782  }
783
784  hihd.arg = dst;
785  bsp_interrupt_server_call_helper(
786    src,
787    vector,
788    0,
789    NULL,
790    &hihd,
791    bsp_interrupt_server_handler_move_helper
792  );
793  return RTEMS_SUCCESSFUL;
794}
795
796static void bsp_interrupt_server_entry_suspend_helper(void *arg)
797{
798  bsp_interrupt_server_helper_data *hd = arg;
799  rtems_event_set events;
800
801  rtems_event_transient_send(hd->task);
802  rtems_event_system_receive(
803    RTEMS_EVENT_SYSTEM_SERVER_RESUME,
804    RTEMS_WAIT,
805    RTEMS_NO_TIMEOUT,
806    &events
807  );
808}
809
810rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
811{
812  rtems_status_code sc;
813  bsp_interrupt_server_context *s;
814
815  s = bsp_interrupt_server_get_context(server_index, &sc);
816  if (s == NULL) {
817    return sc;
818  }
819
820  bsp_interrupt_server_call_helper(
821    s,
822    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
823    0,
824    NULL,
825    NULL,
826    bsp_interrupt_server_entry_suspend_helper
827  );
828  return RTEMS_SUCCESSFUL;
829}
830
831rtems_status_code rtems_interrupt_server_resume(uint32_t server_index)
832{
833  rtems_status_code sc;
834  bsp_interrupt_server_context *s;
835
836  s = bsp_interrupt_server_get_context(server_index, &sc);
837  if (s == NULL) {
838    return sc;
839  }
840
841  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER_RESUME);
842  bsp_interrupt_server_call_helper(
843    s,
844    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
845    0,
846    NULL,
847    NULL,
848    bsp_interrupt_server_entry_synchronize_helper
849  );
850  return RTEMS_SUCCESSFUL;
851}
852
853rtems_status_code rtems_interrupt_server_set_affinity(
854  uint32_t            server_index,
855  size_t              affinity_size,
856  const cpu_set_t    *affinity,
857  rtems_task_priority priority
858)
859{
860  rtems_status_code sc;
861  bsp_interrupt_server_context *s;
862  rtems_id scheduler;
863
864  s = bsp_interrupt_server_get_context(server_index, &sc);
865  if (s == NULL) {
866    return sc;
867  }
868
869  sc = rtems_scheduler_ident_by_processor_set(
870    affinity_size,
871    affinity,
872    &scheduler
873  );
874  if (sc != RTEMS_SUCCESSFUL) {
875    return sc;
876  }
877
878  sc = rtems_task_set_scheduler(s->server, scheduler, priority);
879  if (sc != RTEMS_SUCCESSFUL) {
880    return sc;
881  }
882
883  return rtems_task_set_affinity(s->server, affinity_size, affinity);
884}
Note: See TracBrowser for help on using the repository browser.