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]);
103 size = atoi(argv[1]);
105 /* create a new scheduler */
106 sched = sched_new(size);
109 XBT_INFO("sched_new() failed : errno %d", errno);
113 __argv = xbt_new0(char *, MAX_ARGS);
115 for (i = 0; i < MAX_ARGS; i++) {
116 sprintf(arg, "arg_%d", i);
117 __argv[i] = strdup(arg);
118 memset(arg, 0, MAX_ARG);
122 for (i = 0; i < size; i++)
124 job_new(job, (i < MAX_ARGS) ? i : MAX_ARGS, __argv));
126 /* initialize the scheduler */
127 if (sched_init(sched) < 0) {
129 XBT_INFO("sched_init() failed : errno %d\n", errno);
133 /* schedule the jobs */
134 if (sched_schedule(sched) < 0) {
136 XBT_INFO("sched_init() failed : errno %d", errno);
141 if (sched_clean(sched) < 0) {
143 XBT_INFO("sched_init() failed : errno %d", errno);
147 /* destroy the scheduler */
150 XBT_INFO("sem_sched terminated with exit code %d (success)", EXIT_SUCCESS);
156 void *ctx_function(void *param)
160 ctx_t ctx = (ctx_t) param;
162 XBT_INFO("Hello i'm the owner of the context %d, i'm waiting for starting",
168 XBT_INFO("0ups the scheduler initialization failed bye {%d}.",
170 xbt_os_thread_exit(&exit_code);
173 XBT_INFO("I'm the owner of the context %d : I'm started", ctx->index);
174 XBT_INFO("Wait a minute, I do my job");
177 exit_code = job_execute(ctx->job);
179 XBT_INFO("Have finished my job, bye {%d}\n", ctx->index);
181 xbt_os_sem_release(ctx->end);
183 xbt_os_thread_exit(&exit_code);
186 void schedule(ctx_t c)
188 xbt_os_sem_release(c->begin); /* allow C to go */
189 xbt_os_sem_acquire(c->end); /* wait C's end */
192 void unschedule(ctx_t c)
194 xbt_os_sem_release(c->end); /* I'm done, dude */
195 xbt_os_sem_acquire(c->begin); /* can I start again? */
198 ctx_t ctx_new(job_t job)
200 ctx_t ctx = xbt_new0(s_ctx_t, 1);
201 ctx->index = ++__next_ctx_ID;
202 ctx->begin = xbt_os_sem_init(0);
203 ctx->end = xbt_os_sem_init(0);
210 int ctx_free(ctx_t * ref)
218 xbt_os_sem_destroy(ctx->begin);
219 xbt_os_sem_destroy(ctx->end);
220 job_free(&(ctx->job));
227 sched_t sched_new(int size)
236 sched = xbt_new0(s_sched_t, 1);
243 sched->ctxs = xbt_new0(ctx_t, size);
245 if (!(sched->ctxs)) {
252 sched->capacity = size;
257 int sched_add_job(sched_t sched, job_t job)
262 if (sched->capacity < sched->size)
265 sched->ctxs[(sched->size)++] = ctx_new(job);
270 int sched_init(sched_t sched)
278 for (i = 0; i < sched->size; i++) {
279 sched->ctxs[i]->imp =
280 xbt_os_thread_create("thread", ctx_function,
281 (void *) sched->ctxs[i]);
283 xbt_os_sem_acquire(sched->ctxs[i]->end);
287 for (j = 0; j < i; j++) {
288 sched->ctxs[j]->failure = 1;
289 xbt_os_sem_release(sched->ctxs[j]->begin);
292 for (j = 0; j < i; j++) {
293 xbt_os_thread_join(sched->ctxs[j]->imp, 0);
295 ctx_free(&(sched->ctxs[j]));
305 int sched_schedule(sched_t sched)
312 for (i = 0; i < sched->size; i++)
313 schedule(sched->ctxs[i]);
318 int sched_clean(sched_t sched)
325 for (i = 0; i < sched->size; i++) {
326 xbt_os_thread_join(sched->ctxs[i]->imp, NULL);
328 ctx_free(&(sched->ctxs[i]));
334 int sched_free(sched_t * ref)
339 free(((sched_t) (*ref))->ctxs);
347 int job(int argc, char **argv)
352 ("I'm the job : I'm going to print all the args of my commande line");
354 XBT_INFO("-- Arguments (%d):", argc);
356 for (i = 0; i < argc; i++)
357 XBT_INFO(" ---- [%i] %s", i, argv[i]);
362 job_t job_new(pfn_func_t func, int argc, char **argv)
367 /* todo check the parameters */
368 job = xbt_new0(s_job_t, 1);
375 job->argv = xbt_new0(char *, argc);
383 for (i = 0; i < argc; i++)
384 job->argv[i] = strdup(argv[i]);
392 int job_execute(job_t job)
397 return job->func(job->argc, job->argv);
400 int job_free(job_t * ref)
410 for (i = 0; i < job->argc; i++)