3 #include <ros/resource.h>
4 #include <ros/procdata.h>
17 # define udelay(x) udelay((x)/2000)
25 struct event_queue *indirect_q;
26 static void handle_generic(struct event_msg *ev_msg, unsigned int ev_type,
29 void ghetto_vcore_entry(void);
30 struct uthread *ghetto_init(void)
32 struct uthread *uthread = malloc(sizeof(struct uthread));
33 memset(uthread, 0, sizeof(struct uthread));
37 struct uthread *ghetto_create(void (*func)(void), void *data)
42 struct schedule_ops ghetto_sched_ops = {
43 .sched_init = ghetto_init,
44 .sched_entry = ghetto_vcore_entry,
45 .thread_create = ghetto_create,
47 struct schedule_ops *sched_ops = &ghetto_sched_ops;
49 /* to trick uthread_create() */
54 int main(int argc, char** argv)
59 mcs_barrier_init(&b, max_vcores());
61 /* vcore_context test */
62 assert(!in_vcore_context());
64 /* prep indirect ev_q. Note we grab a big one */
65 indirect_q = get_big_event_q();
66 indirect_q->ev_flags = EVENT_IPI;
67 indirect_q->ev_vcore = 1; /* IPI core 1 */
68 indirect_q->ev_handler = 0;
69 printf("Registering %08p for event type %d\n", indirect_q,
71 register_kevent_q(indirect_q, EV_FREE_APPLE_PIE);
73 /* handle events: just want to print out what we get. This is just a
74 * quick set of handlers, not a registration for a kevent. */
75 for (int i = 0; i < MAX_NR_EVENT; i++)
76 ev_handlers[i] = handle_generic;
77 /* Want to use the default ev_ev (which we just overwrote) */
78 ev_handlers[EV_EVENT] = handle_ev_ev;
79 /* vcore_init() done in vcore_request() now. */
80 /* Set up event reception. For example, this will allow us to receive an
81 * event and IPI for USER_IPIs on vcore 0. Check event.c for more stuff.
82 * Note you don't have to register for USER_IPIs to receive ones you send
83 * yourself with sys_self_notify(). */
84 enable_kevent(EV_USER_IPI, 0, EVENT_IPI);
85 /* Receive pending preemption events. Can also get a MSG if you want. */
86 struct event_queue *ev_q = get_event_q();
87 ev_q->ev_flags = EVENT_IPI | EVENT_NOMSG | EVENT_VCORE_APPRO;
88 register_kevent_q(ev_q, EV_PREEMPT_PENDING);
90 /* Makes a thread for us, though we won't use it. Just a hack to get into
91 * _M mode. Note this requests one vcore for us */
92 uthread_create(dummy, 0);
94 if ((vcoreid = vcore_id())) {
95 printf("Should never see me! (from vcore %d)\n", vcoreid);
98 printf("Hello from vcore %d with temp addr = %p and temp = %p\n",
99 vcoreid, &temp, temp);
100 printf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
101 //retval = sys_resource_req(RES_CORES, 2, 0);
102 printf("Requesting %d vcores\n", max_vcores() - 1);
103 retval = vcore_request(max_vcores() - 1); /* since we already have 1 */
104 //retval = vcore_request(5);
105 printf("This is vcore0, right after vcore_request, retval=%d\n", retval);
106 /* vcore_context test */
107 assert(!in_vcore_context());
110 /* test notifying my vcore2 */
112 printf("Vcore 0 self-notifying vcore 2 with notif 4!\n");
113 struct event_msg msg;
115 sys_self_notify(2, 4, &msg);
117 printf("Vcore 0 notifying itself with notif 3!\n");
119 sys_notify(sys_getpid(), 3, &msg);
122 /* test loop for restarting a notif_tf */
126 printf("Vcore %d Spinning (%d), temp = %08x!\n", vcoreid, ctr++, temp);
132 printf("Vcore %d Done!\n", vcoreid);
133 //mcs_barrier_wait(&b,vcore_id());
135 printf("All Cores Done!\n", vcoreid);
136 while(1); // manually kill from the monitor
140 static void handle_generic(struct event_msg *ev_msg, unsigned int ev_type,
143 printf("Got event type %d on vcore %d, with%s overflow\n",
144 ev_type, vcore_id(), overflow ? "" : "out");
147 void ghetto_vcore_entry(void)
149 uint32_t vcoreid = vcore_id();
150 static bool first_time = TRUE;
153 /* vcore_context test (don't need to do this anywhere) */
154 assert(in_vcore_context());
156 /* old logic was moved to parlib code */
157 if (current_uthread) {
158 assert(vcoreid == 0);
159 run_current_uthread();
161 /* unmask notifications once you can let go of the notif_tf and it is okay
162 * to clobber the transition stack.
163 * Check Documentation/processes.txt: 4.2.4. In real code, you should be
164 * popping the tf of whatever user process you want (get off the x-stack) */
165 enable_notifs(vcoreid);
167 /* end: stuff userspace needs to do to handle notifications */
169 printf("Hello from vcore_entry in vcore %d with temp addr %p and temp %p\n",
170 vcoreid, &temp, temp);
172 //mcs_barrier_wait(&b,vcore_id());
173 udelay(vcoreid * 10000000);