/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <time.h>
+#include <roken.h>
/* allocate externs here */
#define LWP_KERNEL
#include "lwp.h"
+
#ifdef AFS_AIX32_ENV
#include <ulimit.h>
#include <sys/errno.h>
#pragma alloca
int setlim(int limcon, uchar_t hard, int limit);
#endif
-#ifdef AFS_SGI64_ENV
-extern char *getenv();
-#include <time.h>
-#endif
-#include <string.h>
-#if !defined(USE_PTHREADS) && !defined(USE_SOLARIS_THREADS)
-
-#ifdef AFS_OSF_ENV
-extern void *malloc(int size);
-extern void *realloc(void *ptr, int size);
-#endif
#ifndef AFS_ARM_LINUX20_ENV
-#if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
-extern int PRE_Block; /* from preempt.c */
+#if defined(AFS_S390_LINUX20_ENV)
+int PRE_Block; /* Remnants of preemption support. */
#else
-extern char PRE_Block; /* from preempt.c */
+char PRE_Block; /* Remnants of preemption support. */
#endif
#endif
#define MAXINT (~(1<<((sizeof(int)*8)-1)))
#define MINSTACK 44
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
#define MINFRAME 128
#define STACK_ALIGN 8
#else
; \
} while (0)
#endif
-\f
+
static void Dispatcher(void);
static void Create_Process_Part2(void);
static void Exit_LWP(void);
static afs_int32 Initialize_Stack(char *stackptr, int stacksize);
-static int Stack_Used(register char *stackptr, int stacksize);
+static int Stack_Used(char *stackptr, int stacksize);
static void Abort_LWP(char *msg);
static void Overflow_Complain(void);
static void Initialize_PCB(PROCESS temp, int priority, char *stack,
- int stacksize, void *(*ep)(void *), void *parm,
+ int stacksize, void *(*ep)(void *), void *parm,
char *name);
static void Dispose_of_Dead_PCB(PROCESS cur);
static void Free_PCB(PROCESS pid);
static int Internal_Signal(void *event);
static int purge_dead_pcbs(void);
static int LWP_MwaitProcess(int wcount, void *evlist[]);
-
+
#define MAX_PRIORITIES (LWP_MAX_PRIORITY+1)
PROCESS head;
int count;
} runnable[MAX_PRIORITIES], blocked, qwaiting;
-/* Invariant for runnable queues: The head of each queue points to the
- * currently running process if it is in that queue, or it points to the
+/* Invariant for runnable queues: The head of each queue points to the
+ * currently running process if it is in that queue, or it points to the
* next process in that queue that should run. */
/* Offset of stack field within pcb -- used by stack checking stuff */
int lwp_MinStackSize = 0;
static int
-lwp_remove(register PROCESS p, register struct QUEUE *q)
+lwp_remove(PROCESS p, struct QUEUE *q)
{
/* Special test for only element on queue */
if (q->count == 1)
}
static int
-insert(register PROCESS p, register struct QUEUE *q)
+insert(PROCESS p, struct QUEUE *q)
{
if (q->head == NULL) { /* Queue is empty */
q->head = p;
/* Iterator macro */
#define for_all_elts(var, q, body)\
{\
- register PROCESS var, _NEXT_;\
- register int _I_;\
+ PROCESS var, _NEXT_;\
+ int _I_;\
for (_I_=q.count, var = q.head; _I_>0; _I_--, var=_NEXT_) {\
_NEXT_ = var -> next;\
body\
}\
}
-\f
+
/* */
/*****************************************************************************\
* *
int
LWP_QWait(void)
{
- register PROCESS tp;
+ PROCESS tp;
(tp = lwp_cpptr)->status = QWAITING;
move(tp, &runnable[tp->priority], &qwaiting);
Set_LWP_RC();
}
int
-LWP_QSignal(register PROCESS pid)
+LWP_QSignal(PROCESS pid)
{
if (pid->status == QWAITING) {
pid->status = READY;
#ifdef AFS_AIX32_ENV
char *
-reserveFromStack(register afs_int32 size)
+reserveFromStack(afs_int32 size)
{
char *x;
x = alloca(size);
/* Throw away all dead process control blocks */
purge_dead_pcbs();
if (lwp_init) {
- temp = (PROCESS) malloc(sizeof(struct lwp_pcb));
+ temp = malloc(sizeof(struct lwp_pcb));
if (temp == NULL) {
Set_LWP_RC();
return LWP_ENOMEM;
#ifdef AFS_AIX32_ENV
if (!stackptr) {
/*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
+ * The following signal action for AIX is necessary so that in case of a
+ * crash (i.e. core is generated) we can include the user's data section
* in the core dump. Unfortunately, by default, only a partial core is
* generated which, in many cases, isn't too useful.
*
/*
* First we need to increase the default resource limits,
* if necessary, so that we can guarantee that we have the
- * resources to create the core file, but we can't always
+ * resources to create the core file, but we can't always
* do it as an ordinary user.
*/
if (!geteuid()) {
stackmemory = stackptr;
#else
#ifdef AFS_DARWIN_ENV
- if ((stackmemory = (char *)malloc(stacksize + STACK_ALIGN - 1)) == NULL)
+ if ((stackmemory = malloc(stacksize + STACK_ALIGN - 1)) == NULL)
#else /* !AFS_DARWIN_ENV */
- if ((stackmemory = (char *)malloc(stacksize + 7)) == NULL)
+ if ((stackmemory = malloc(stacksize + 7)) == NULL)
#endif /* !AFS_DARWIN_ENV */
{
+ free(temp);
Set_LWP_RC();
return LWP_ENOMEM;
}
#endif /* !AFS_DARWIN_ENV */
#endif
if (priority < 0 || priority >= MAX_PRIORITIES) {
+ free(temp);
+#ifndef AFS_AIX32_ENV
+ free(stackmemory);
+#endif
Set_LWP_RC();
return LWP_EBADPRI;
}
Initialize_PCB(temp, priority, stackmemory, stacksize, ep, parm, name);
insert(temp, &runnable[priority]);
temp2 = lwp_cpptr;
-#ifndef AFS_ARM_LINUX20_ENV
+#if !defined(AFS_ARM_LINUX20_ENV) && !defined(AFS_ARM_DARWIN_ENV)
if (PRE_Block != 0)
Abort_LWP("PRE_Block not 0");
PRE_Block = 1;
#endif
lwp_cpptr = temp;
-#if defined(AFS_PARISC_LINUX24_ENV)
- savecontext(Create_Process_Part2, &temp2->context,
- stackptr + MINFRAME);
-#else
#ifdef __hp9000s800
savecontext(Create_Process_Part2, &temp2->context,
stackptr + MINFRAME);
#endif /* AFS_SPARC64_LINUX20_ENV || AFS_SPARC_LINUX20_ENV */
#endif /* AFS_SGI62_ENV */
#endif
-#endif
/* End of gross hack */
Set_LWP_RC();
- *pid = temp;
+ if (pid)
+ *pid = temp;
return 0;
} else
return LWP_EINIT;
/* Throw away all dead process control blocks */
purge_dead_pcbs();
if (lwp_init) {
- temp = (PROCESS) malloc(sizeof(struct lwp_pcb));
+ temp = malloc(sizeof(struct lwp_pcb));
if (temp == NULL) {
Set_LWP_RC();
return LWP_ENOMEM;
else
stacksize =
STACK_ALIGN * ((stacksize + STACK_ALIGN - 1) / STACK_ALIGN);
- if ((stackptr = (char *)malloc(stacksize)) == NULL) {
+ if ((stackptr = malloc(stacksize)) == NULL) {
Set_LWP_RC();
return LWP_ENOMEM;
}
Initialize_PCB(temp, priority, stackptr, stacksize, ep, parm, name);
insert(temp, &runnable[priority]);
temp2 = lwp_cpptr;
-#ifndef AFS_ARM_LINUX20_ENV
+#if !defined(AFS_ARM_LINUX20_ENV) && !defined(AFS_ARM_DARWIN_ENV)
if (PRE_Block != 0)
Abort_LWP("PRE_Block not 0");
/* End of gross hack */
Set_LWP_RC();
- *pid = temp;
+ if (pid)
+ *pid = temp;
return 0;
} else
return LWP_EINIT;
pid->status = DESTROYED;
move(pid, &runnable[pid->priority], &blocked);
temp = lwp_cpptr;
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
savecontext(Dispatcher, &(temp->context),
&(LWPANCHOR.dsptchstack[MINFRAME]));
#elif defined(AFS_SGI62_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
Dump_Processes(void)
{
if (lwp_init) {
- register int i;
+ int i;
for (i = 0; i < MAX_PRIORITIES; i++)
for_all_elts(x, runnable[i], {
printf("[Priority %d]\n", i);
{
PROCESS temp;
struct lwp_pcb dummy;
- register int i;
+ int i;
char *value;
Debug(0, ("Entered LWP_InitializeProcessSupport"));
blocked.count = 0;
qwaiting.head = NULL;
qwaiting.count = 0;
- lwp_init = (struct lwp_ctl *)malloc(sizeof(struct lwp_ctl));
- temp = (PROCESS) malloc(sizeof(struct lwp_pcb));
+ lwp_init = malloc(sizeof(struct lwp_ctl));
+ temp = malloc(sizeof(struct lwp_pcb));
if (lwp_init == NULL || temp == NULL)
Abort_LWP("Insufficient Storage to Initialize LWP Support");
LWPANCHOR.processcnt = 1;
savecontext(Dispatcher, &temp->context, NULL);
LWPANCHOR.outersp = temp->context.topstack;
Set_LWP_RC();
- *pid = temp;
+ if (pid)
+ *pid = temp;
/* get minimum stack size from the environment. this allows the administrator
* to change the lwp stack dynamically without getting a new binary version.
int
LWP_TerminateProcessSupport(void)
{ /* terminate all LWP support */
- register int i;
+ int i;
Debug(0, ("Entered Terminate_Process_Support"));
if (lwp_init == NULL)
int
LWP_MwaitProcess(int wcount, void *evlist[])
{ /* wait on m of n events */
- register int ecount, i;
+ int ecount, i;
Debug(0, ("Entered Mwait_Process [waitcnt = %d]", wcount));
}
if (ecount > lwp_cpptr->eventlistsize) {
- lwp_cpptr->eventlist =
- (void **)realloc(lwp_cpptr->eventlist,
- ecount * sizeof(void *));
+ lwp_cpptr->eventlist = realloc(lwp_cpptr->eventlist,
+ ecount * sizeof(void *));
lwp_cpptr->eventlistsize = ecount;
}
for (i = 0; i < ecount; i++)
return LWP_NO_STACK;
return LWP_SUCCESS;
}
-\f
+
/*
* The following functions are strictly
* INTERNAL to the LWP support package.
}
static int
-Delete_PCB(register PROCESS pid)
+Delete_PCB(PROCESS pid)
{ /* remove a PCB from the process list */
Debug(4, ("Entered Delete_PCB"));
lwp_remove(pid,
(pid->blockflag || pid->status == WAITING
|| pid->status ==
- DESTROYED ? &blocked :
+ DESTROYED ? &blocked :
(pid->status == QWAITING) ? &qwaiting :
&runnable[pid->priority]));
LWPANCHOR.processcnt--;
static void
Dispatcher(void)
{ /* Lightweight process dispatcher */
- register int i;
+ int i;
#ifdef DEBUG
static int dispatch_count = 0;
* the guard word at the front of the stack being damaged and
* for the stack pointer being below the front of the stack.
* WARNING! This code assumes that stacks grow downward. */
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
/* Fix this (stackcheck at other end of stack?) */
if (lwp_cpptr != NULL && lwp_cpptr->stack != NULL
&& (lwp_cpptr->stackcheck !=
#endif
printf("stackcheck = %u: stack = %u \n", lwp_cpptr->stackcheck,
*(int *)lwp_cpptr->stack);
- printf("topstack = 0x%x: stackptr = 0x%x: stacksize = 0x%x\n",
- (uintptr_t)lwp_cpptr->context.topstack,
- (uintptr_t)lwp_cpptr->stack,
+ printf("topstack = %p: stackptr = %p: stacksize = 0x%x\n",
+ (void *)(uintptr_t)lwp_cpptr->context.topstack,
+ (void *)(uintptr_t)lwp_cpptr->stack,
lwp_cpptr->stacksize);
switch (lwp_overflowAction) {
printf("Dispatch %d [PCB at 0x%x] \"%s\"\n", ++dispatch_count,
runnable[i].head, runnable[i].head->name);
#endif
-#ifndef AFS_ARM_LINUX20_ENV
+#if !defined(AFS_ARM_LINUX20_ENV) && !defined(AFS_ARM_DARWIN_ENV)
if (PRE_Block != 1)
Abort_LWP("PRE_Block not 1");
#endif
lwp_cpptr = runnable[i].head;
returnto(&lwp_cpptr->context);
-
+
return; /* not reachable */
}
currenttime = time(0);
timeStamp = ctime(¤ttime);
timeStamp[24] = 0;
- write(2, timeStamp, strlen(timeStamp));
+ if (write(2, timeStamp, strlen(timeStamp)) < 0)
+ return;
- write(2, msg1, strlen(msg1));
- write(2, lwp_cpptr->name, strlen(lwp_cpptr->name));
- write(2, msg2, strlen(msg2));
+ if (write(2, msg1, strlen(msg1)) < 0)
+ return;
+ if (write(2, lwp_cpptr->name, strlen(lwp_cpptr->name)) < 0)
+ return;
+ if (write(2, msg2, strlen(msg2)) < 0)
+ return;
}
static void
Initialize_PCB(PROCESS temp, int priority, char *stack, int stacksize,
void *(*ep) (void *), void *parm, char *name)
{
- register int i = 0;
+ int i = 0;
Debug(4, ("Entered Initialize_PCB"));
if (name != NULL)
i++;
temp->name[31] = '\0';
temp->status = READY;
- temp->eventlist = (void **)malloc(EVINITSIZE * sizeof(void *));
+ temp->eventlist = malloc(EVINITSIZE * sizeof(void *));
temp->eventlistsize = EVINITSIZE;
temp->eventcnt = 0;
temp->wakevent = 0;
temp->index = lwp_nextindex++;
temp->stack = stack;
temp->stacksize = stacksize;
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
if (temp->stack != NULL)
temp->stackcheck = *(int *)((temp->stack) + stacksize - 4);
#else
}
static int
-Internal_Signal(register void *event)
+Internal_Signal(void *event)
{
int rc = LWP_ENOWAIT;
- register int i;
+ int i;
Debug(0, ("Entered Internal_Signal [event id 0x%x]", event));
if (!lwp_init)
static afs_int32
Initialize_Stack(char *stackptr, int stacksize)
{
- register int i;
+ int i;
Debug(4, ("Entered Initialize_Stack"));
if (lwp_stackUseEnabled)
for (i = 0; i < stacksize; i++)
stackptr[i] = i & 0xff;
else
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
*(afs_int32 *) (stackptr + stacksize - 4) = STACKMAGIC;
#else
*(afs_int32 *) stackptr = STACKMAGIC;
}
static int
-Stack_Used(register char *stackptr, int stacksize)
+Stack_Used(char *stackptr, int stacksize)
{
- register int i;
+ int i;
-#if defined(__hp9000s800) || defined(AFS_PARISC_LINUX24_ENV)
+#if defined(__hp9000s800)
if (*(afs_int32 *) (stackptr + stacksize - 4) == STACKMAGIC)
return 0;
else {
* LWP_SUCCESS Rock did not exist and a new one was used
* LWP_EBADROCK Rock already exists.
* LWP_ENOROCKS All rocks are in use.
- *
+ *
* From the above semantics, you can only set a rock value once. This is specifically
* to prevent multiple users of the LWP package from accidentally using the same Tag
* value and clobbering others. You can always use one level of indirection to obtain
* a rock whose contents can change.
*/
{
- register int i;
- register struct rock *ra; /* rock array */
+ int i;
+ struct rock *ra; /* rock array */
ra = lwp_cpptr->lwp_rlist;
* LWP_EBADROCK rock specified does not exist
*/
{
- register int i;
- register struct rock *ra;
+ int i;
+ struct rock *ra;
ra = lwp_cpptr->lwp_rlist;
}
return (0);
}
-
-
-#ifdef notdef
-/*
- * Print the specific limit out
- */
-int
-plim(char *name, afs_int32 lc, uchar_t hard)
-{
- struct rlimit rlim;
- int lim;
-
- printf("%s \t", name);
- (void)getrlimit(lc, &rlim);
- lim = hard ? rlim.rlim_max : rlim.rlim_cur;
- if (lim == RLIM_INFINITY)
- printf("unlimited");
- printf("%d %s", lim / 1024, "kbytes");
- printf("\n");
-}
-#endif
#endif
#ifdef AFS_SUN5_ENV
}
#endif
-#else
-#ifdef USE_SOLARIS_THREADS
-#include <thread.h>
-#else
-#include "pthread.h"
-#endif
-#include <stdio.h>
-#include <assert.h>
-
-pthread_mutex_t lwp_mutex; /* Mutex to ensure mutual exclusion of all LWP threads */
-
-PROCESS lwp_process_list; /* List of LWP initiated threads */
-
-pthread_key_t lwp_process_key; /* Key associating lwp pid with thread */
-
-#define CHECK check(__LINE__);
-
-typedef struct event {
- struct event *next; /* next in hash chain */
- void *event; /* lwp event: an address */
- int refcount; /* Is it in use? */
- pthread_cond_t cond; /* Currently associated condition variable */
- int seq; /* Sequence number: this is incremented
- * by wakeup calls; wait will not return until
- * it changes */
-} event_t;
-
-#define HASHSIZE 127
-event_t *hashtable[HASHSIZE]; /* Hash table for events */
-#define hash(event) ((unsigned long) (event) % HASHSIZE);
-
-#if CMA_DEBUG || DEBUGF
-char *
-lwp_process_string(void)
-{
- static char id[200];
- PROCESS p;
- LWP_CurrentProcess(&p);
- sprintf(id, "PID %x <%s>", p, p->name);
- return id;
-}
-#endif
-
-void
-lwp_unimplemented(char *interface)
-{
- fprintf(stderr,
- "cmalwp: %s is not currently implemented: program aborted\n",
- interface);
- exit(1);
-}
-
-static void
-lwpabort(char *interface)
-{
- fprintf(stderr, "cmalwp: %s failed unexpectedly\n", interface);
- abort();
-}
-
-int
-LWP_QWait(void)
-{
- lwp_unimplemented("LWP_QWait");
-}
-
-int
-LWP_QSignal(int pid)
-{
- lwp_unimplemented("LWP_QSignal");
-}
-
-/* Allocate and initialize an LWP process handle. The associated pthread handle
- * must be added by the caller, and the structure threaded onto the LWP active
- * process list by lwp_thread_process */
-static PROCESS
-lwp_alloc_process(char *name, pthread_startroutine_t ep, pthread_addr_t arg)
-{
- PROCESS lp;
- assert(lp = (PROCESS) malloc(sizeof(*lp)));
- memset((char *)lp, 0, sizeof(*lp));
- if (!name) {
- char temp[100];
- static procnum;
- sprintf(temp, "unnamed_process_%04d", ++procnum);
- assert(name = (char *)malloc(strlen(temp) + 1));
- strcpy(name, temp);
- }
- lp->name = name;
- lp->ep = ep;
- lp->arg = arg;
- return lp;
-}
-
-/* Thread the LWP process descriptor *lp onto the lwp active process list
- * and associate a back pointer to the process descriptor from the associated
- * thread */
-static
-lwp_thread_process(PROCESS lp)
-{
- lp->next = lwp_process_list;
- lwp_process_list = lp;
- assert(!pthread_setspecific(lwp_process_key, (pthread_addr_t) lp));
-}
-
-/* The top-level routine used as entry point to explicitly created LWP
- * processes. This completes a few details of process creation left
- * out by LWP_CreateProcess and calls the user-specified entry point */
-static int
-lwp_top_level(pthread_addr_t argp)
-{
- PROCESS lp = (PROCESS) argp;
-
- assert(!pthread_mutex_lock(&lwp_mutex));
- lwp_thread_process(lp);
- (lp->ep) (lp->arg);
- assert(!pthread_mutex_unlock(&lwp_mutex));
- /* Should cleanup state */
-}
-
-int
-LWP_CreateProcess(pthread_startroutine_t ep, int stacksize, int priority,
- void *parm, char *name, PROCESS * pid)
-{
- int status;
- pthread_attr_t attr;
- pthread_t handle;
- PROCESS lp;
-
-#ifndef LWP_NO_PRIORITIES
- if (!cmalwp_pri_inrange(priority))
- return LWP_EBADPRI;
-#endif
- assert(!pthread_attr_create(&attr));
- assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
- if (stacksize)
- assert(!pthread_attr_setstacksize(&attr, stacksize));
-#ifndef BDE_THREADS
- (void)pthread_attr_setinheritsched(&attr, PTHREAD_DEFAULT_SCHED);
- (void)pthread_attr_setsched(&attr, SCHED_FIFO);
-#ifndef LWP_NO_PRIORITIES
- (void)pthread_attr_setprio(&attr, cmalwp_lwppri_to_cmapri(priority));
-#endif
-#endif
- lp = lwp_alloc_process(name, (pthread_startroutine_t) ep,
- (pthread_addr_t) parm);
-
- /* allow new thread to run if higher priority */
- assert(!pthread_mutex_unlock(&lwp_mutex));
- /* process is only added to active list after first time it runs (it adds itself) */
- status =
- pthread_create(&lp->handle, attr,
- (pthread_startroutine_t) lwp_top_level,
- (pthread_addr_t) lp);
- assert(!pthread_attr_delete(&attr));
- assert(!pthread_mutex_lock(&lwp_mutex));
- if (status != 0) {
- free(lp);
- return LWP_ENOMEM;
- }
- *pid = lp;
- return LWP_SUCCESS;
-}
-
-PROCESS
-LWP_ActiveProcess(void)
-{ /* returns pid of current process */
- PROCESS pid;
- assert(!pthread_getspecific(lwp_process_key, (pthread_addr_t *) & pid));
- return pid;
-}
-
-int
-LWP_CurrentProcess(PROCESS * pid)
-{ /* get pid of current process */
- assert(!pthread_getspecific(lwp_process_key, (pthread_addr_t *) pid));
- return LWP_SUCCESS;
-}
-
-int
-LWP_DestroyProcess(PROCESS pid)
-{ /* destroy a lightweight process */
- lwp_unimplemented("LWP_DestroyProcess");
-}
-
-int
-LWP_DispatchProcess(void)
-{ /* explicit voluntary preemption */
- assert(!pthread_mutex_unlock(&lwp_mutex));
- pthread_yield();
- assert(!pthread_mutex_lock(&lwp_mutex));
- return LWP_SUCCESS;
-}
-
-static int
-lwp_process_key_destructor(void)
-{
-}
-
-int
-LWP_InitializeProcessSupport(int priority, PROCESS * pid)
-{
- static int initialized = 0;
- int status;
- static PROCESS lp;
- extern main;
- int state;
-
- if (initialized) {
- *pid = lp;
- return LWP_SUCCESS;
- }
-#ifndef LWP_NO_PRIORITIES
- if (priority < 0 || priority > LWP_MAX_PRIORITY)
- return LWP_EBADPRI;
-#endif
-
- /* Create pthread key to associate LWP process descriptor with each
- * LWP-created thread */
- assert(!pthread_keycreate(&lwp_process_key, (pthread_destructor_t)
- lwp_process_key_destructor));
-
- lp = lwp_alloc_process("main process", main, 0);
- lp->handle = pthread_self();
- lwp_thread_process(lp);
-#ifndef LWP_NO_PRIORITIES
- (void)pthread_setscheduler(pthread_self(), SCHED_FIFO,
- cmalwp_lwppri_to_cmapri(priority));
-
-#endif
- assert(pthread_mutex_init(&lwp_mutex, MUTEX_FAST_NP) == 0);
- assert(pthread_mutex_lock(&lwp_mutex) == 0);
- initialized = 1;
- *pid = lp;
- return LWP_SUCCESS;
-}
-
-int
-LWP_TerminateProcessSupport(void)
-{ /* terminate all LWP support */
- lwp_unimplemented("LWP_TerminateProcessSupport");
-}
-
-/* Get and initialize event structure corresponding to lwp event (i.e. address) */
-static event_t *
-getevent(void *event)
-{
- event_t *evp, *newp;
- int hashcode;
-
- hashcode = hash(event);
- evp = hashtable[hashcode];
- newp = 0;
- while (evp) {
- if (evp->event == event) {
- evp->refcount++;
- return evp;
- }
- if (evp->refcount == 0)
- newp = evp;
- evp = evp->next;
- }
- if (!newp) {
- newp = (event_t *) malloc(sizeof(event_t));
- assert(newp);
- newp->next = hashtable[hashcode];
- hashtable[hashcode] = newp;
- assert(!pthread_cond_init(&newp->cond, ((pthread_condattr_t) 0)));
- newp->seq = 0;
- }
- newp->event = event;
- newp->refcount = 1;
- return newp;
-}
-
-/* Release the specified event */
-#define relevent(evp) ((evp)->refcount--)
-
-int
-LWP_WaitProcess(void *event)
-{ /* wait on a single event */
- struct event *ev;
- int seq;
- debugf(("%s: wait process (%x)\n", lwp_process_string(), event));
- if (event == NULL)
- return LWP_EBADEVENT;
- ev = getevent(event);
- seq = ev->seq;
- while (seq == ev->seq) {
- assert(pthread_cond_wait(&ev->cond, &lwp_mutex) == 0);
- }
- debugf(("%s: Woken up (%x)\n", lwp_process_string(), event));
- relevent(ev);
- return LWP_SUCCESS;
-}
-
-int
-LWP_MwaitProcess(int wcount, char *evlist[])
-{ /* wait on m of n events */
- lwp_unimplemented("LWP_MWaitProcess");
-}
-
-int
-LWP_NoYieldSignal(void *event)
-{
- struct event *ev;
- debugf(("%s: no yield signal (%x)\n", lwp_process_string(), event));
- if (event == NULL)
- return LWP_EBADEVENT;
- ev = getevent(event);
- if (ev->refcount > 1) {
- ev->seq++;
- assert(pthread_cond_broadcast(&ev->cond) == 0);
- }
- relevent(ev);
- return LWP_SUCCESS;
-}
-
-int
-LWP_SignalProcess(void *event)
-{
- struct event *ev;
- debugf(("%s: signal process (%x)\n", lwp_process_string(), event));
- if (event == NULL)
- return LWP_EBADEVENT;
- ev = getevent(event);
- if (ev->refcount > 1) {
- ev->seq++;
- assert(!pthread_mutex_unlock(&lwp_mutex));
- assert(!pthread_cond_broadcast(&ev->cond));
- pthread_yield();
- assert(!pthread_mutex_lock(&lwp_mutex));
- }
- relevent(ev);
- return LWP_SUCCESS;
-}
-
-int
-LWP_StackUsed(PROCESS pid, int *maxa, int *used)
-{
- lwp_unimplemented("LWP_StackUsed");
-}
-
-int
-LWP_NewRock(int Tag, char *Value)
-{
- lwp_unimplemented("LWP_NewRock");
-}
-
-int
-LWP_GetRock(int Tag, char **Value)
-{
- lwp_unimplemented("LWP_GetRock");
-}
-
-int
-LWP_GetProcessPriority(PROCESS pid, int *priority)
-{ /* returns process priority */
- lwp_unimplemented("LWP_GetProcessPriority");
-}
-
-#endif /* USE_PTHREADS */