The Pedigree Project 0.1
input.c
1#define _GNU_SOURCE
2#include <signal.h>
3#include <stdlib.h>
4#include <unistd.h>
5
6#include "contract.h"
7
8/* The SDK library exports these C wrappers without an installed input header. */
9extern void pedigree_input_install_callback(void*, uint32_t, uintptr_t);
10extern void pedigree_input_remove_callback(void*);
11extern int pedigree_event_return(void);
12
13static void input_callback(size_t first, size_t second, uintptr_t* buffer, size_t fourth) {
14 (void)first;
15 (void)second;
16 (void)buffer;
17 (void)fourth;
18 pedigree_event_return();
19}
20
21static int retained_pin(int source, int destination) {
22 int failed = 0;
23 cpu_set_t actual;
24 if (source != destination) {
25 errno = 0;
26 CHECK(sc_pin(0, destination) == -1 && errno == EOPNOTSUPP);
27 }
28 CHECK(sched_getaffinity(0, sizeof(actual), &actual) == 0);
29 CHECK(CPU_EQUAL(&actual, &sc_allowed));
30 CHECK(sc_sample(source) == 0);
31out:
32 return failed;
33}
34
35int sc_input_exec(int argc, char** argv) {
36 int failed = 0;
37 alarm(15);
38 CHECK(argc == 5);
39 int source = atoi(argv[2]), destination = atoi(argv[3]), expected = atoi(argv[4]);
40 CHECK(source >= 0 && source < CPU_SETSIZE && destination >= 0 && destination < CPU_SETSIZE);
41 CHECK(expected > 0 && expected <= CPU_SETSIZE);
42 CHECK(sc_init(expected) == 0);
43 CHECK(CPU_ISSET(source, &sc_allowed) && CPU_ISSET(destination, &sc_allowed));
44 CHECK(sc_tls == 0);
45 sc_tls = 0x5176a92b;
46 CHECK(sc_pin(0, destination) == 0);
47 CHECK(sc_mask(0, destination) == 0 && sc_sample(destination) == 0);
48 CHECK(sc_tls == 0x5176a92b);
49out:
50 return failed;
51}
52
53int sc_input(void) {
54 int failed = 0;
55 const int source = sc_cpus[0], destination = sc_cpus[sc_count - 1];
56 CHECK(sc_pin(0, source) == 0);
57 CHECK(sc_mask(0, source) == 0 && sc_sample(source) == 0);
58 if (source != destination) {
59 CHECK(sc_pin(0, destination) == 0 && sc_sample(destination) == 0);
60 CHECK(sc_pin(0, source) == 0 && sc_sample(source) == 0);
61 }
62
63 pedigree_input_install_callback((void*)input_callback, 1, 0);
64 CHECK(sc_pin(0, source) == 0);
65 CHECK(sc_mask(0, source) == 0 && sc_sample(source) == 0);
66 CHECK(sched_setaffinity(0, sizeof(sc_allowed), &sc_allowed) == 0);
67 if (sc_count == 1)
68 puts("SCHEDULING-CONTRACT: SKIP input pin exclusion (one allowed CPU)");
69 CHECK(retained_pin(source, destination) == 0);
70
71 /* Removal stops producers; this image retains its callback-domain pin. */
72 pedigree_input_remove_callback((void*)input_callback);
73 CHECK(retained_pin(source, destination) == 0);
74 execl("/applications/scheduling-no-such-image", "absent", (char*)NULL);
75 CHECK(errno == ENOENT);
76 CHECK(retained_pin(source, destination) == 0);
77
78 char from[16], to[16], count[16];
79 snprintf(from, sizeof(from), "%d", source);
80 snprintf(to, sizeof(to), "%d", destination);
81 snprintf(count, sizeof(count), "%d", sc_count);
82 execl(SC_APP, SC_APP, "schedule-input-exec", from, to, count, (char*)NULL);
83 CHECK(0);
84out:
85 return failed;
86}