1 /* Copyright (c) 2007, 2008. 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,"Messages specific for this sem example");
22 #define CTX_MAX ((unsigned int)1000)
28 typedef int (*pfn_func_t)(int, char**);
42 job_new(pfn_func_t func, int argc, char** argv);
45 job_execute(job_t job);
50 /* an entry of the table of threads */
75 ctx_function(void* param);
87 sched_add_job(sched_t sched, job_t job);
90 sched_init(sched_t sched);
93 sched_schedule(sched_t sched);
96 sched_clean(sched_t sched);
99 sched_free(sched_t* ref);
102 job(int argc, char* argv[]);
105 main(int argc, char* argv[])
110 char arg[MAX_ARG] = {0};
113 xbt_init(&argc, argv);
117 INFO1("Usage: %s job count",argv[0]);
122 size = atoi(argv[1]);
124 /* create a new scheduler */
125 sched = sched_new(size);
129 INFO1("sched_new() failed : errno %d",errno);
134 __argv = xbt_new0(char*,MAX_ARGS);
136 for(i = 0; i < MAX_ARGS; i++)
138 sprintf(arg,"arg_%d",i);
139 __argv[i] = strdup(arg);
140 memset(arg,0,MAX_ARG);
144 for(i = 0; i < size; i++)
145 sched_add_job(sched,job_new(job,(i < MAX_ARGS) ? i : MAX_ARGS,__argv));
147 /* initialize the scheduler */
148 if(sched_init(sched) < 0)
151 INFO1("sched_init() failed : errno %d\n",errno);
156 /* schedule the jobs */
157 if(sched_schedule(sched) < 0)
160 INFO1("sched_init() failed : errno %d",errno);
166 if(sched_clean(sched) < 0)
169 INFO1("sched_init() failed : errno %d",errno);
174 /* destroy the scheduler */
177 INFO1("sem_sched terminated with exit code %d (success)",EXIT_SUCCESS);
186 ctx_function(void* param)
190 ctx_t ctx = (ctx_t)param;
192 INFO1("Hello i'm the owner of the context %d, i'm waiting for starting",ctx->index);
198 INFO1("0ups the scheduler initialization failed bye {%d}.",ctx->index);
199 xbt_os_thread_exit(&exit_code);
202 INFO1("I'm the owner of the context %d : I'm started",ctx->index);
203 INFO0("Wait a minute, I do my job");
206 exit_code = job_execute(ctx->job);
208 INFO1("Have finished my job, bye {%d}\n",ctx->index);
210 xbt_os_sem_release(ctx->end);
212 xbt_os_thread_exit(&exit_code);
215 void schedule(ctx_t c)
217 xbt_os_sem_release(c->begin); /* allow C to go */
218 xbt_os_sem_acquire(c->end); /* wait C's end */
221 void unschedule(ctx_t c)
223 xbt_os_sem_release(c->end); /* I'm done, dude */
224 xbt_os_sem_acquire(c->begin); /* can I start again? */
230 ctx_t ctx = xbt_new0(s_ctx_t,1);
231 ctx->index = ++__next_ctx_ID;
232 ctx->begin = xbt_os_sem_init(0);
233 ctx->end = xbt_os_sem_init(0);
249 xbt_os_sem_destroy(ctx->begin);
250 xbt_os_sem_destroy(ctx->end);
251 job_free(&(ctx->job));
269 sched = xbt_new0(s_sched_t,1);
277 sched->ctxs = xbt_new0(ctx_t,size);
287 sched->capacity = size;
293 sched_add_job(sched_t sched, job_t job)
298 if(sched->capacity < sched->size)
301 sched->ctxs[(sched->size)++] = ctx_new(job);
307 sched_init(sched_t sched)
315 for(i = 0; i < sched->size; i++)
317 sched->ctxs[i]->imp = xbt_os_thread_create("thread",ctx_function,(void*)sched->ctxs[i]);
319 xbt_os_sem_acquire(sched->ctxs[i]->end);
324 for(j = 0; j < i; j++)
326 sched->ctxs[j]->failure = 1;
327 xbt_os_sem_release(sched->ctxs[j]->begin);
330 for(j = 0; j < i; j++)
332 xbt_os_thread_join(sched->ctxs[j]->imp,0);
334 ctx_free(&(sched->ctxs[j]));
345 sched_schedule(sched_t sched)
352 for(i = 0; i < sched->size; i++)
353 schedule(sched->ctxs[i]);
359 sched_clean(sched_t sched)
366 for(i = 0; i < sched->size; i++)
368 xbt_os_thread_join(sched->ctxs[i]->imp,NULL);
370 ctx_free(&(sched->ctxs[i]));
377 sched_free(sched_t* ref)
382 free(((sched_t)(*ref))->ctxs);
391 job(int argc, char** argv)
395 INFO0("I'm the job : I'm going to print all the args of my commande line");
397 INFO1("-- Arguments (%d):",argc);
399 for(i = 0; i < argc; i++)
400 INFO2(" ---- [%i] %s",i,argv[i]);
406 job_new(pfn_func_t func, int argc, char** argv)
411 /* todo check the parameters */
412 job = xbt_new0(s_job_t,1);
420 job->argv = xbt_new0(char*,argc);
429 for(i = 0; i < argc; i++)
430 job->argv[i] = strdup(argv[i]);
439 job_execute(job_t job)
444 return (*(job->func))(job->argc, job->argv);
458 for(i = 0; i < job->argc; i++)