1 /* Copyright (c) 2007-2008, 2010-2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
13 #include "xbt/xbt_os_thread.h"
16 XBT_LOG_NEW_DEFAULT_CATEGORY(sem_sched,
17 "Messages specific for this sem example");
23 #define CTX_MAX ((unsigned int)1000)
29 typedef int (*pfn_func_t) (int, char **);
34 typedef struct s_job {
41 job_t job_new(pfn_func_t func, int argc, char **argv);
43 int job_execute(job_t job);
45 int job_free(job_t * ref);
47 /* an entry of the table of threads */
48 typedef struct s_ctx {
57 typedef struct s_shed {
61 } s_sched_t, *sched_t;
64 void schedule(ctx_t c);
65 void unschedule(ctx_t c);
67 void *ctx_function(void *param);
69 ctx_t ctx_new(job_t job);
71 int ctx_free(ctx_t * ref);
73 sched_t sched_new(int size);
75 int sched_add_job(sched_t sched, job_t job);
77 int sched_init(sched_t sched);
79 int sched_schedule(sched_t sched);
81 int sched_clean(sched_t sched);
83 int sched_free(sched_t * ref);
85 int job(int argc, char *argv[]);
87 int main(int argc, char *argv[])
92 char arg[MAX_ARG] = { 0 };
95 xbt_init(&argc, argv);
98 XBT_INFO("Usage: %s job count", argv[0]);
102 size = xbt_str_parse_int(argv[1], "Invalid size: %s");
104 /* create a new scheduler */
105 sched = sched_new(size);
108 XBT_INFO("sched_new() failed : errno %d", errno);
112 __argv = xbt_new0(char *, MAX_ARGS);
114 for (i = 0; i < MAX_ARGS; i++) {
115 __argv[i] = bprintf("arg_%d", i);
118 for (i = 0; i < size; i++)
120 job_new(job, (i < MAX_ARGS) ? i : MAX_ARGS, __argv));
122 /* initialize the scheduler */
123 if (sched_init(sched) < 0) {
125 XBT_INFO("sched_init() failed : errno %d\n", errno);
129 /* schedule the jobs */
130 if (sched_schedule(sched) < 0) {
132 XBT_INFO("sched_init() failed : errno %d", errno);
137 if (sched_clean(sched) < 0) {
139 XBT_INFO("sched_init() failed : errno %d", errno);
143 /* destroy the scheduler */
146 XBT_INFO("sem_sched terminated with exit code %d (success)", EXIT_SUCCESS);
152 void *ctx_function(void *param)
156 ctx_t ctx = (ctx_t) param;
158 XBT_INFO("Hello i'm the owner of the context %d, i'm waiting for starting",
164 XBT_INFO("0ups the scheduler initialization failed bye {%d}.",
166 xbt_os_thread_exit(&exit_code);
169 XBT_INFO("I'm the owner of the context %d : I'm started", ctx->index);
170 XBT_INFO("Wait a minute, I do my job");
173 exit_code = job_execute(ctx->job);
175 XBT_INFO("Have finished my job, bye {%d}\n", ctx->index);
177 xbt_os_sem_release(ctx->end);
179 xbt_os_thread_exit(&exit_code);
182 void schedule(ctx_t c)
184 xbt_os_sem_release(c->begin); /* allow C to go */
185 xbt_os_sem_acquire(c->end); /* wait C's end */
188 void unschedule(ctx_t c)
190 xbt_os_sem_release(c->end); /* I'm done, dude */
191 xbt_os_sem_acquire(c->begin); /* can I start again? */
194 ctx_t ctx_new(job_t job)
196 ctx_t ctx = xbt_new0(s_ctx_t, 1);
197 ctx->index = ++__next_ctx_ID;
198 ctx->begin = xbt_os_sem_init(0);
199 ctx->end = xbt_os_sem_init(0);
206 int ctx_free(ctx_t * ref)
214 xbt_os_sem_destroy(ctx->begin);
215 xbt_os_sem_destroy(ctx->end);
216 job_free(&(ctx->job));
223 sched_t sched_new(int size)
232 sched = xbt_new0(s_sched_t, 1);
239 sched->ctxs = xbt_new0(ctx_t, size);
241 if (!(sched->ctxs)) {
248 sched->capacity = size;
253 int sched_add_job(sched_t sched, job_t job)
258 if (sched->capacity < sched->size)
261 sched->ctxs[(sched->size)++] = ctx_new(job);
266 int sched_init(sched_t sched)
274 for (i = 0; i < sched->size; i++) {
275 sched->ctxs[i]->imp =
276 xbt_os_thread_create("thread", ctx_function,
277 (void *) sched->ctxs[i]);
279 xbt_os_sem_acquire(sched->ctxs[i]->end);
283 for (j = 0; j < i; j++) {
284 sched->ctxs[j]->failure = 1;
285 xbt_os_sem_release(sched->ctxs[j]->begin);
288 for (j = 0; j < i; j++) {
289 xbt_os_thread_join(sched->ctxs[j]->imp, 0);
291 ctx_free(&(sched->ctxs[j]));
301 int sched_schedule(sched_t sched)
308 for (i = 0; i < sched->size; i++)
309 schedule(sched->ctxs[i]);
314 int sched_clean(sched_t sched)
321 for (i = 0; i < sched->size; i++) {
322 xbt_os_thread_join(sched->ctxs[i]->imp, NULL);
324 ctx_free(&(sched->ctxs[i]));
330 int sched_free(sched_t * ref)
335 free(((sched_t) (*ref))->ctxs);
343 int job(int argc, char **argv)
348 ("I'm the job : I'm going to print all the args of my commande line");
350 XBT_INFO("-- Arguments (%d):", argc);
352 for (i = 0; i < argc; i++)
353 XBT_INFO(" ---- [%i] %s", i, argv[i]);
358 job_t job_new(pfn_func_t func, int argc, char **argv)
363 /* todo check the parameters */
364 job = xbt_new0(s_job_t, 1);
371 job->argv = xbt_new0(char *, argc);
379 for (i = 0; i < argc; i++)
380 job->argv[i] = strdup(argv[i]);
388 int job_execute(job_t job)
393 return job->func(job->argc, job->argv);
396 int job_free(job_t * ref)
406 for (i = 0; i < job->argc; i++)