Exemplo n.º 1
0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *args) {
    
    int stacksize; // Stack size
    int initial_state; // Initial state
    int res;

    // Get some arguments need for the thread creation
    if (attr) {
        stacksize = attr->stack_size;
        if (stacksize < PTHREAD_STACK_MIN) {
            errno = EINVAL;
            return EINVAL;
        }
        initial_state = attr->initial_state;
    } else {
        stacksize = PTHREAD_STACK_MIN;
        initial_state = PTHREAD_INITIAL_STATE_RUN;
    }
     
    // Create a new pthread
    res = _pthread_create(thread, stacksize, initial_state, start_routine, args);
    if (res) {
        errno = res;
        return res;
    }
       
    return 0;
}
Exemplo n.º 2
0
void init_horse(struct horse *ph, const char *name, pthread_mutex_t *rm, pthread_cond_t *rc, pthread_barrier_t *rb, struct service *service) {
	strncpy(ph->name, name, HORSE_NAME);
	ph->name[HORSE_NAME] = 0;
	if (ph->name[strlen(ph->name) - 1] == 0xa)
		ph->name[strlen(ph->name) - 1] = 0;
	ph->strength = HORSE_START_STRENGTH;
	ph->distance = 0;
	ph->running = 0;
	ph->mutex = rm;
	ph->cond = rc;
	ph->barrier = rb;
	ph->service = service;
	_pthread_create(&(ph->tid), NULL, horse_thread, (void *)ph);
}
Exemplo n.º 3
0
void server_work(int listenfd, pthread_cond_t *cond, struct service *service, struct horse *horses, size_t horse_num) {
	pthread_t tid;
	int *iptr;
	struct sockaddr_in cliaddr;
	struct user *user;
	socklen_t clilen;

	// for signal handling
	t_sigmask(SIGINT, SIG_UNBLOCK);
	t_sigmask(SIGALRM, SIG_UNBLOCK);	
	
	// set alarm for next run
	choose_run_horses(horses, horse_num, service);

	alarm(service->delay);

	while (work) {
		// accepting client, while there is no run
		if (!run) {
			clilen = sizeof(cliaddr); 
			iptr = _malloc(sizeof(int));
			*iptr = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);	
			if (*iptr < 0) {
				if (errno == EINTR)
					continue;
			}
			if (run) {
				free(iptr);
				continue;
			}
			user = (struct user *)_malloc(sizeof(struct user));
			user->sockfd = iptr;
			user->service = service;
			user->mnr = service->mnr;
			user->mhb = service->mhb;
			_pthread_create(&tid, NULL, client_thread, user);		
		}
		else play(cond, service, horses, horse_num);
	}

	_close(listenfd);
}
Exemplo n.º 4
0
/* Override standard thread creation function with our own
 * which if thread creation succeeds will call our created_new_thread
 * function to possibly set its stack name.
 */
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start)(void *), void *arg)
{
  pthread_t tid = 0;
  int rval;

  /* Make sure all the original functions are available */
  if( ensure_intercepts() < 0 )
    return -EOPNOTSUPP;
  /* Call the original function to create the thread */
  rval = _pthread_create(&tid, attr, start, arg);

  /* If it succeeds, go check if we need to rename it */
  if( rval >= 0 )
    created_new_thread(tid);
  /* Return the thread id via this pointer */
  if( thread )
    *thread = tid;

  LOG("pthread_create returning %d", rval);
  return rval;
}
Exemplo n.º 5
0
int
_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
	       void *(*start_routine) (void *), void *arg)
{
	struct pthread	*curthread = _get_curthread();
	struct itimerval itimer;
	int		f_gc = 0;
	int             ret = 0;
	pthread_t       gc_thread;
	pthread_t       new_thread;
	pthread_attr_t	pattr;
	void           *stack;
#if !defined(__ia64__)
	u_long 		stackp;
#endif

	if (thread == NULL)
		return(EINVAL);

	/*
	 * Locking functions in libc are required when there are
	 * threads other than the initial thread.
	 */
	__isthreaded = 1;

	/* Allocate memory for the thread structure: */
	if ((new_thread = (pthread_t) malloc(sizeof(struct pthread))) == NULL) {
		/* Insufficient memory to create a thread: */
		ret = EAGAIN;
	} else {
		/* Check if default thread attributes are required: */
		if (attr == NULL || *attr == NULL) {
			/* Use the default thread attributes: */
			pattr = &_pthread_attr_default;
		} else {
			pattr = *attr;
		}
		/* Check if a stack was specified in the thread attributes: */
		if ((stack = pattr->stackaddr_attr) != NULL) {
		}
		/* Allocate a stack: */
		else {
			stack = _thread_stack_alloc(pattr->stacksize_attr,
			    pattr->guardsize_attr);
			if (stack == NULL) {
				ret = EAGAIN;
				free(new_thread);
			}
		}

		/* Check for errors: */
		if (ret != 0) {
		} else {
			/* Initialise the thread structure: */
			memset(new_thread, 0, sizeof(struct pthread));
			new_thread->slice_usec = -1;
			new_thread->stack = stack;
			new_thread->start_routine = start_routine;
			new_thread->arg = arg;

			new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
			    PTHREAD_CANCEL_DEFERRED;

			/*
			 * Write a magic value to the thread structure
			 * to help identify valid ones:
			 */
			new_thread->magic = PTHREAD_MAGIC;

			/* Initialise the thread for signals: */
			new_thread->sigmask = curthread->sigmask;
			new_thread->sigmask_seqno = 0;

			/* Initialize the signal frame: */
			new_thread->curframe = NULL;

			/* Initialise the jump buffer: */
			_setjmp(new_thread->ctx.jb);

			/*
			 * Set up new stack frame so that it looks like it
			 * returned from a longjmp() to the beginning of
			 * _thread_start().
			 */
			SET_RETURN_ADDR_JB(new_thread->ctx.jb, _thread_start);

#if !defined(__ia64__)
			stackp = (long)new_thread->stack + pattr->stacksize_attr - sizeof(double);
#if defined(__amd64__)
			stackp &= ~0xFUL;
#endif
			/* The stack starts high and builds down: */
			SET_STACK_JB(new_thread->ctx.jb, stackp);
#else
			SET_STACK_JB(new_thread->ctx.jb,
			    (long)new_thread->stack, pattr->stacksize_attr);
#endif

			/* Copy the thread attributes: */
			memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));

			/*
			 * Check if this thread is to inherit the scheduling
			 * attributes from its parent:
			 */
			if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
				/* Copy the scheduling attributes: */
				new_thread->base_priority =
				    curthread->base_priority &
				    ~PTHREAD_SIGNAL_PRIORITY;
				new_thread->attr.prio =
				    curthread->base_priority &
				    ~PTHREAD_SIGNAL_PRIORITY;
				new_thread->attr.sched_policy =
				    curthread->attr.sched_policy;
			} else {
				/*
				 * Use just the thread priority, leaving the
				 * other scheduling attributes as their
				 * default values:
				 */
				new_thread->base_priority =
				    new_thread->attr.prio;
			}
			new_thread->active_priority = new_thread->base_priority;
			new_thread->inherited_priority = 0;

			/* Initialize joiner to NULL (no joiner): */
			new_thread->joiner = NULL;

			/* Initialize the mutex queue: */
			TAILQ_INIT(&new_thread->mutexq);

			/* Initialise hooks in the thread structure: */
			new_thread->specific = NULL;
			new_thread->cleanup = NULL;
			new_thread->flags = 0;
			new_thread->poll_data.nfds = 0;
			new_thread->poll_data.fds = NULL;
			new_thread->continuation = NULL;

			/*
			 * Defer signals to protect the scheduling queues
			 * from access by the signal handler:
			 */
			_thread_kern_sig_defer();

			/*
			 * Initialise the unique id which GDB uses to
			 * track threads.
			 */
			new_thread->uniqueid = next_uniqueid++;

			/*
			 * Check if the garbage collector thread
			 * needs to be started.
			 */
			f_gc = (TAILQ_FIRST(&_thread_list) == _thread_initial);

			/* Add the thread to the linked list of all threads: */
			TAILQ_INSERT_HEAD(&_thread_list, new_thread, tle);

			if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) {
				new_thread->flags |= PTHREAD_FLAGS_SUSPENDED;
				new_thread->state = PS_SUSPENDED;
			} else {
				new_thread->state = PS_RUNNING;
				PTHREAD_PRIOQ_INSERT_TAIL(new_thread);
			}

			/*
			 * Undefer and handle pending signals, yielding
			 * if necessary.
			 */
			_thread_kern_sig_undefer();

			/* Return a pointer to the thread structure: */
			(*thread) = new_thread;

			if (f_gc != 0) {
				/* Install the scheduling timer: */
				itimer.it_interval.tv_sec = 0;
				itimer.it_interval.tv_usec = _clock_res_usec;
				itimer.it_value = itimer.it_interval;
				if (setitimer(_ITIMER_SCHED_TIMER, &itimer,
				    NULL) != 0)
					PANIC("Cannot set interval timer");
			}

			/* Schedule the new user thread: */
			_thread_kern_sched(NULL);

			/*
			 * Start a garbage collector thread
			 * if necessary.
			 */
			if (f_gc && _pthread_create(&gc_thread, NULL,
				    _thread_gc, NULL) != 0)
				PANIC("Can't create gc thread");

		}
	}

	/* Return the status: */
	return (ret);
}