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);
133 __argv = xbt_new0(char*,MAX_ARGS);
135 for(i = 0; i < MAX_ARGS; i++)
137 sprintf(arg,"arg_%d",i);
138 __argv[i] = strdup(arg);
139 memset(arg,0,MAX_ARG);
143 for(i = 0; i < size; i++)
144 sched_add_job(sched,job_new(job,(i < MAX_ARGS) ? i : MAX_ARGS,__argv));
146 /* initialize the scheduler */
147 if(sched_init(sched) < 0)
150 INFO1("sched_init() failed : errno %d\n",errno);
154 /* schedule the jobs */
155 if(sched_schedule(sched) < 0)
158 INFO1("sched_init() failed : errno %d",errno);
163 if(sched_clean(sched) < 0)
166 INFO1("sched_init() failed : errno %d",errno);
170 /* destroy the scheduler */
173 INFO1("sem_sched terminated with exit code %d (success)",EXIT_SUCCESS);
180 ctx_function(void* param)
184 ctx_t ctx = (ctx_t)param;
186 INFO1("Hello i'm the owner of the context %d, i'm waiting for starting",ctx->index);
192 INFO1("0ups the scheduler initialization failed bye {%d}.",ctx->index);
193 xbt_os_thread_exit(&exit_code);
196 INFO1("I'm the owner of the context %d : I'm started",ctx->index);
197 INFO0("Wait a minute, I do my job");
200 exit_code = job_execute(ctx->job);
202 INFO1("Have finished my job, bye {%d}\n",ctx->index);
204 xbt_os_sem_release(ctx->end);
206 xbt_os_thread_exit(&exit_code);
209 void schedule(ctx_t c)
211 xbt_os_sem_release(c->begin); /* allow C to go */
212 xbt_os_sem_acquire(c->end); /* wait C's end */
215 void unschedule(ctx_t c)
217 xbt_os_sem_release(c->end); /* I'm done, dude */
218 xbt_os_sem_acquire(c->begin); /* can I start again? */
224 ctx_t ctx = xbt_new0(s_ctx_t,1);
225 ctx->index = ++__next_ctx_ID;
226 ctx->begin = xbt_os_sem_init(0);
227 ctx->end = xbt_os_sem_init(0);
243 xbt_os_sem_destroy(ctx->begin);
244 xbt_os_sem_destroy(ctx->end);
245 job_free(&(ctx->job));
263 sched = xbt_new0(s_sched_t,1);
271 sched->ctxs = xbt_new0(ctx_t,size);
281 sched->capacity = size;
287 sched_add_job(sched_t sched, job_t job)
292 if(sched->capacity < sched->size)
295 sched->ctxs[(sched->size)++] = ctx_new(job);
301 sched_init(sched_t sched)
309 for(i = 0; i < sched->size; i++)
311 sched->ctxs[i]->imp = xbt_os_thread_create("thread",ctx_function,(void*)sched->ctxs[i]);
313 xbt_os_sem_acquire(sched->ctxs[i]->end);
318 for(j = 0; j < i; j++)
320 sched->ctxs[j]->failure = 1;
321 xbt_os_sem_release(sched->ctxs[j]->begin);
324 for(j = 0; j < i; j++)
326 xbt_os_thread_join(sched->ctxs[j]->imp,0);
328 ctx_free(&(sched->ctxs[j]));
339 sched_schedule(sched_t sched)
346 for(i = 0; i < sched->size; i++)
347 schedule(sched->ctxs[i]);
353 sched_clean(sched_t sched)
360 for(i = 0; i < sched->size; i++)
362 xbt_os_thread_join(sched->ctxs[i]->imp,NULL);
364 ctx_free(&(sched->ctxs[i]));
371 sched_free(sched_t* ref)
376 free(((sched_t)(*ref))->ctxs);
385 job(int argc, char** argv)
389 INFO0("I'm the job : I'm going to print all the args of my commande line");
391 INFO1("-- Arguments (%d):",argc);
393 for(i = 0; i < argc; i++)
394 INFO2(" ---- [%i] %s",i,argv[i]);
400 job_new(pfn_func_t func, int argc, char** argv)
405 /* todo check the parameters */
406 job = xbt_new0(s_job_t,1);
414 job->argv = xbt_new0(char*,argc);
423 for(i = 0; i < argc; i++)
424 job->argv[i] = strdup(argv[i]);
433 job_execute(job_t job)
438 return (*(job->func))(job->argc, job->argv);
452 for(i = 0; i < job->argc; i++)