Commit e53c9fc7 authored by sof's avatar sof
Browse files

[project @ 2002-02-04 20:24:14 by sof]

Factor out the task handling into separate 'module'.
[Tasks represent native threads that execute STG code, with this
 module providing the API which the Scheduler uses to control
 their creation and destruction.]
parent 2374f2fd
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team 2001-
*
* The task manager subsystem. Tasks execute STG code, with this
* module providing the API which the Scheduler uses to control their
* creation and destruction.
*
* Two kinds of RTS builds uses 'tasks' - the SMP and the
* 'native thread-friendly' builds.
*
* The SMP build lets multiple tasks concurrently execute STG code,
* all sharing vital internal RTS data structures in a controlled manner.
*
* The 'threads' build has at any one time only one task executing STG
* code, other tasks are either busy executing code outside the RTS
* (e.g., a ccall) or waiting for their turn to (again) evaluate some
* STG code. A task relinquishes its RTS token when it is asked to
* evaluate an external (C) call.
*
* -------------------------------------------------------------------------*/
#include "Rts.h"
#if defined(RTS_SUPPORTS_THREADS) /* to the end */
#include "RtsUtils.h"
#include "OSThreads.h"
#include "Task.h"
#include "Stats.h"
#include "RtsFlags.h"
static TaskInfo* taskTable;
static nat maxTasks; /* upper bound / the number of tasks created. */
static nat taskCount; /* number of tasks currently created */
#if defined(SMP)
void
startTaskManager( nat maxCount, void (*taskStart)(void) )
{
nat i;
static int initialized = 0;
if (!initialized) {
taskCount = 0;
maxTasks = maxCount;
/* allocate table holding task metadata */
if (maxCount > 0) {
taskTable = stgMallocBytes(maxCount * sizeof(TaskInfo),
"startTaskManager:tasks");
/* and eagerly create them all. */
for (i = 0; i < maxCount; i++) {
startTask(taskStart);
taskCount++;
}
}
initialized = 1;
}
}
#else
void
startTaskManager( nat maxCount, void (*taskStart)(void) )
{
/* In the threaded case, maxCount is used to limit the
the creation of worker tasks. Tasks are created lazily, i.e.,
when the current task gives up the token on executing
STG code.
*/
maxTasks = maxCount;
taskCount = 0;
}
#endif
void
startTask ( void (*taskStart)(void) )
{
int r;
OSThreadId tid;
r = createOSThread(&tid,taskStart);
if (r != 0) {
barf("startTask: Can't create new task");
}
#if defined(SMP)
taskTable[taskCount].id = tid;
taskTable[taskCount].mut_time = 0.0;
taskTable[taskCount].mut_etime = 0.0;
taskTable[taskCount].gc_time = 0.0;
taskTable[taskCount].gc_etime = 0.0;
taskTable[taskCount].elapsedtimestart = stat_getElapsedTime();
#endif
IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Started task: %ld\n",tid););
return;
}
#if defined(SMP)
void
stopTaskManager ()
{
nat i;
/* Don't want to use pthread_cancel, since we'd have to install
* these silly exception handlers (pthread_cleanup_{push,pop}) around
* all our locks.
*/
#if 0
/* Cancel all our tasks */
for (i = 0; i < RtsFlags.ParFlags.nNodes; i++) {
pthread_cancel(taskTable[i].id);
}
/* Wait for all the tasks to terminate */
for (i = 0; i < maxCount; i++) {
IF_DEBUG(scheduler,fprintf(stderr,"scheduler: waiting for task %ld\n",
taskTable[i].id));
pthread_join(taskTable[i].id, NULL);
}
#endif
/* Send 'em all a SIGHUP. That should shut 'em up. */
await_death = maxCount;
for (i = 0; i < maxCount; i++) {
pthread_kill(taskTable[i].id,SIGTERM);
}
while (await_death > 0) {
sched_yield();
}
return;
}
#else
void
stopTaskManager ()
{
}
#endif
nat
getTaskCount ()
{
return taskCount;
}
#endif /* RTS_SUPPORTS_THREADS */
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team 2001-
*
* Types + prototypes for functions in Task.cn
* (RTS subsystem for handling OS tasks).
*
* -------------------------------------------------------------------------*/
#ifndef __TASK_H__
#define __TASK_H__
#if defined(RTS_SUPPORTS_THREADS) /* to the end */
/*
* Tasks evaluate STG code; the TaskInfo structure collects together
* misc metadata about a task.
*
*/
typedef struct _TaskInfo {
OSThreadId id;
double elapsedtimestart;
double mut_time;
double mut_etime;
double gc_time;
double gc_etime;
} TaskInfo;
extern TaskInfo *taskIds;
extern void startTaskManager ( nat maxTasks, void (*taskStart)(void) );
extern void stopTaskManager ( void );
extern void startTask ( void (*taskStart)(void) );
extern nat getTaskCount( void );
#endif /* RTS_SUPPORTS_THREADS */
#endif /* __TASK_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment