• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/libubox/tests/test-runqueue.c

  1 /*
  2  * runqueue-example.c
  3  *
  4  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  5  *
  6  * Permission to use, copy, modify, and/or distribute this software for any
  7  * purpose with or without fee is hereby granted, provided that the above
  8  * copyright notice and this permission notice appear in all copies.
  9  *
 10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 17  */
 18 
 19 #include <stdbool.h>
 20 #include <stdlib.h>
 21 #include <stdio.h>
 22 #include <unistd.h>
 23 
 24 #include "uloop.h"
 25 #include "runqueue.h"
 26 
 27 static struct runqueue q;
 28 
 29 struct sleeper {
 30         int val;
 31         bool kill;
 32         struct uloop_timeout t;
 33         struct runqueue_process proc;
 34 };
 35 
 36 static void q_empty(struct runqueue *q)
 37 {
 38         fprintf(stderr, "All done!\n");
 39         uloop_end();
 40 }
 41 
 42 static const char* sleeper_type(struct sleeper *s)
 43 {
 44         return s->kill ? "killer" : "sleeper";
 45 }
 46 
 47 static void q_sleep_run(struct runqueue *q, struct runqueue_task *t)
 48 {
 49         struct sleeper *s = container_of(t, struct sleeper, proc.task);
 50         char str[32];
 51         pid_t pid;
 52 
 53         fprintf(stderr, "[%d/%d] start 'sleep %d' (%s)\n", q->running_tasks,
 54                         q->max_running_tasks, s->val, sleeper_type(s));
 55 
 56         pid = fork();
 57         if (pid < 0)
 58                 return;
 59 
 60         if (pid) {
 61                 runqueue_process_add(q, &s->proc, pid);
 62                 return;
 63         }
 64 
 65         sprintf(str, "%d", s->val);
 66         execlp("sleep", "sleep", str, NULL);
 67         exit(1);
 68 }
 69 
 70 static void q_sleep_cancel(struct runqueue *q, struct runqueue_task *t, int type)
 71 {
 72         struct sleeper *s = container_of(t, struct sleeper, proc.task);
 73 
 74         fprintf(stderr, "[%d/%d] cancel 'sleep %d' (%s)\n", q->running_tasks,
 75                         q->max_running_tasks, s->val, sleeper_type(s));
 76         runqueue_process_cancel_cb(q, t, type);
 77 }
 78 
 79 static void q_sleep_complete(struct runqueue *q, struct runqueue_task *p)
 80 {
 81         struct sleeper *s = container_of(p, struct sleeper, proc.task);
 82 
 83         fprintf(stderr, "[%d/%d] finish 'sleep %d' (%s) \n", q->running_tasks,
 84                         q->max_running_tasks, s->val, sleeper_type(s));
 85         free(s);
 86 }
 87 
 88 static void my_runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *p)
 89 {
 90         struct sleeper *s = container_of(p, struct sleeper, proc.task);
 91 
 92         fprintf(stderr, "[%d/%d] killing process (%s)\n", q->running_tasks,
 93                         q->max_running_tasks, sleeper_type(s));
 94         runqueue_process_kill_cb(q, p);
 95 }
 96 
 97 static void timer_cb(struct uloop_timeout *t)
 98 {
 99         struct sleeper *s = container_of(t, struct sleeper, t);
100         if (s->kill)
101                 runqueue_task_kill(&s->proc.task);
102 }
103 
104 static struct sleeper* create_sleeper(int val, const struct runqueue_task_type *type, bool kill)
105 {
106         struct sleeper *s = calloc(1, sizeof(*s));
107         s->kill = kill;
108         s->t.cb = timer_cb;
109         s->proc.task.type = type;
110         s->proc.task.run_timeout = 500;
111         s->proc.task.complete = q_sleep_complete;
112         s->val = val;
113 
114         return s;
115 }
116 
117 static void add_sleeper(int val)
118 {
119         static const struct runqueue_task_type sleeper_type = {
120                 .run = q_sleep_run,
121                 .cancel = q_sleep_cancel,
122                 .kill = runqueue_process_kill_cb,
123         };
124 
125         static const struct runqueue_task_type killer_type = {
126                 .run = q_sleep_run,
127                 .cancel = q_sleep_cancel,
128                 .kill = my_runqueue_process_kill_cb,
129         };
130 
131         struct sleeper *k = create_sleeper(val, &killer_type, true);
132         uloop_timeout_set(&k->t, 10);
133         uloop_timeout_add(&k->t);
134         runqueue_task_add(&q, &k->proc.task, false);
135 
136         struct sleeper *s = create_sleeper(val, &sleeper_type, false);
137         runqueue_task_add(&q, &s->proc.task, false);
138 }
139 
140 int main(int argc, char **argv)
141 {
142         uloop_init();
143 
144         runqueue_init(&q);
145         q.empty_cb = q_empty;
146         q.max_running_tasks = 1;
147 
148         if (argc > 1)
149                 q.max_running_tasks = atoi(argv[1]);
150 
151         add_sleeper(1);
152         add_sleeper(1);
153         add_sleeper(1);
154 
155         uloop_run();
156         uloop_done();
157 
158         return 0;
159 }
160 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt