mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
a first pass at cleaning up the configure stuff new cothread library started, some experimental stack allocation code...
Original commit message from CVS: * a first pass at cleaning up the configure stuff * new cothread library started, some experimental stack allocation code is in place
This commit is contained in:
parent
132f776069
commit
bf81ebae7c
8 changed files with 237 additions and 244 deletions
|
@ -54,6 +54,8 @@
|
|||
#undef PTH_DMALLOC
|
||||
#undef PTH_NEED_SEPARATE_REGISTER_STACK
|
||||
|
||||
#undef HAVE_LINUXTHREADS
|
||||
|
||||
@BOTTOM@
|
||||
|
||||
#endif /* _PTH_ACDEF_H_ */
|
||||
|
|
|
@ -1764,3 +1764,18 @@ AC_MSG_VERBOSE([$]$2)
|
|||
AC_MSG_VERBOSE([$]$3)
|
||||
])
|
||||
|
||||
dnl Check for LinuxThreads
|
||||
dnl COTHREADS_CHECK_LINUXTHREADS
|
||||
dnl no arguments
|
||||
AC_DEFUN([COTHREADS_CHECK_LINUXTHREADS], [
|
||||
AC_CACHE_CHECK([for LinuxThreads],
|
||||
[cothreads_cv_linuxthreads],
|
||||
[AC_EGREP_CPP(pthread_kill_other_threads_np,
|
||||
[#include <pthread.h>],
|
||||
[cothreads_cv_linuxthreads=yes],
|
||||
[cothreads_cv_linuxthreads=no])
|
||||
])
|
||||
if test $cothreads_cv_linuxthreads = yes; then
|
||||
AC_DEFINE(HAVE_LINUXTHREADS,1,[if you have LinuxThreads])
|
||||
fi
|
||||
])
|
||||
|
|
|
@ -93,157 +93,28 @@ AC_MSG_PART(Mandatory Platform Environment)
|
|||
|
||||
dnl # check for standard headers
|
||||
AC_HEADER_STDC
|
||||
# FIXME
|
||||
AC_HAVE_HEADERS(dnl
|
||||
stdio.h stdlib.h stdarg.h string.h signal.h unistd.h setjmp.h fcntl.h dnl
|
||||
errno.h sys/types.h sys/time.h sys/wait.h sys/socket.h sys/socketcall.h)
|
||||
errno.h sys/types.h)
|
||||
AC_CHECK_FUNCTIONS(dnl
|
||||
gettimeofday select sigaction sigprocmask sigpending sigsuspend)
|
||||
sigaction sigprocmask sigpending sigsuspend)
|
||||
AC_BEGIN_DECISION([mandatory system headers and functions])
|
||||
AC_IFALLYES(dnl
|
||||
header:stdio.h header:stdlib.h header:stdarg.h header:string.h dnl
|
||||
header:signal.h header:unistd.h header:setjmp.h header:fcntl.h header:errno.h dnl
|
||||
header:sys/types.h header:sys/time.h header:sys/wait.h header:sys/socket.h dnl
|
||||
func:gettimeofday func:select func:sigaction func:sigprocmask dnl
|
||||
header:sys/types.h dnl
|
||||
func:sigaction func:sigprocmask dnl
|
||||
func:sigpending func:sigsuspend,
|
||||
AC_DECIDE(fine, [all fine]))
|
||||
AC_END_DECISION
|
||||
|
||||
AC_MSG_PART(Optional Platform Environment)
|
||||
|
||||
dnl # check for the number of signals
|
||||
dnl AC_CHECK_NSIG(PTH_NSIG)
|
||||
|
||||
dnl # check whether poll(2)'s input stuff has to be faked
|
||||
AC_CHECK_FUNCTIONS(poll)
|
||||
AC_CHECK_DEFINE(POLLIN, poll.h)
|
||||
AC_MSG_CHECKING(whether poll(2) facility has to be faked)
|
||||
AC_IFALLYES(func:poll define:POLLIN, PTH_FAKE_POLL=0, PTH_FAKE_POLL=1)
|
||||
if test .$PTH_FAKE_POLL = .1; then
|
||||
msg="yes"
|
||||
else
|
||||
msg="no"
|
||||
fi
|
||||
AC_SUBST(PTH_FAKE_POLL)
|
||||
AC_MSG_RESULT([$msg])
|
||||
|
||||
dnl # check for readv/writev environment
|
||||
AC_HAVE_HEADERS(sys/uio.h)
|
||||
AC_CHECK_FUNCTIONS(readv writev)
|
||||
AC_MSG_CHECKING(whether readv(2)/writev(2) facility has to be faked)
|
||||
AC_IFALLYES(func:readv func:writev header:sys/uio.h, PTH_FAKE_RWV=0, PTH_FAKE_RWV=1)
|
||||
if test .$PTH_FAKE_RWV = .1; then
|
||||
msg="yes"
|
||||
else
|
||||
msg="no"
|
||||
fi
|
||||
AC_SUBST(PTH_FAKE_RWV)
|
||||
AC_MSG_RESULT([$msg])
|
||||
|
||||
dnl # check for various other functions which would be nice to have
|
||||
AC_CHECK_FUNCTIONS(usleep strerror)
|
||||
|
||||
dnl # check for various other headers which we might need
|
||||
AC_HAVE_HEADERS(sys/resource.h net/errno.h)
|
||||
|
||||
dnl # check whether we've to use a non-standard #include <sys/select.h> to get
|
||||
dnl # the definition for fd_set under AIX and other brain-dead platforms.
|
||||
AC_HAVE_HEADERS(sys/select.h)
|
||||
EXTRA_INCLUDE_SYS_SELECT_H="#include <sys/select.h>"
|
||||
if test ".$ac_cv_header_sys_select_h" != .yes; then
|
||||
EXTRA_INCLUDE_SYS_SELECT_H="/* $EXTRA_INCLUDE_SYS_SELECT_H */"
|
||||
fi
|
||||
AC_SUBST(EXTRA_INCLUDE_SYS_SELECT_H)
|
||||
|
||||
dnl # check whether we've to define sig_atomic_t
|
||||
AC_CHECK_TYPEDEF(sig_atomic_t, signal.h)
|
||||
FALLBACK_SIG_ATOMIC_T="typedef int sig_atomic_t;"
|
||||
if test ".$ac_cv_typedef_sig_atomic_t" = .yes; then
|
||||
FALLBACK_SIG_ATOMIC_T="/* $FALLBACK_SIG_ATOMIC_T */"
|
||||
fi
|
||||
AC_SUBST(FALLBACK_SIG_ATOMIC_T)
|
||||
|
||||
dnl # check whether we've to define pid_t
|
||||
AC_CHECK_TYPEDEF(pid_t, sys/types.h)
|
||||
FALLBACK_PID_T="typedef int pid_t;"
|
||||
if test ".$ac_cv_typedef_pid_t" = .yes; then
|
||||
FALLBACK_PID_T="/* $FALLBACK_PID_T */"
|
||||
fi
|
||||
AC_SUBST(FALLBACK_PID_T)
|
||||
|
||||
dnl # check whether we've to define size_t
|
||||
AC_CHECK_TYPEDEF(size_t, stdlib.h)
|
||||
FALLBACK_SIZE_T="typedef unsigned int size_t;"
|
||||
if test ".$ac_cv_typedef_size_t" = .yes; then
|
||||
FALLBACK_SIZE_T="/* $FALLBACK_SIZE_T */"
|
||||
fi
|
||||
AC_SUBST(FALLBACK_SIZE_T)
|
||||
|
||||
dnl # check whether we've to define ssize_t
|
||||
AC_CHECK_TYPEDEF(ssize_t, sys/types.h)
|
||||
FALLBACK_SSIZE_T="typedef unsigned int ssize_t;"
|
||||
if test ".$ac_cv_typedef_ssize_t" = .yes; then
|
||||
FALLBACK_SSIZE_T="/* $FALLBACK_SSIZE_T */"
|
||||
fi
|
||||
AC_SUBST(FALLBACK_SSIZE_T)
|
||||
|
||||
dnl # check whether we've to define off_t
|
||||
AC_CHECK_TYPEDEF(off_t, sys/types.h)
|
||||
FALLBACK_OFF_T="typedef int off_t;"
|
||||
if test ".$ac_cv_typedef_off_t" = .yes; then
|
||||
FALLBACK_OFF_T="/* $FALLBACK_OFF_T */"
|
||||
fi
|
||||
AC_SUBST(FALLBACK_OFF_T)
|
||||
|
||||
dnl # check whether stack_t exists instead of sigaltstack
|
||||
AC_CHECK_TYPEDEF(stack_t, signal.h)
|
||||
|
||||
dnl # check whether ss_base instead of ss_sp attribute exists
|
||||
AC_CHECK_STRUCTATTR(ss_base, sigaltstack, sys/signal.h)
|
||||
AC_CHECK_STRUCTATTR(ss_sp, sigaltstack, sys/signal.h)
|
||||
|
||||
dnl # check for gettimeofday() variant
|
||||
AC_MSG_CHECKING(for a single-argument based gettimeofday)
|
||||
cross_compile=no
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
],[
|
||||
struct timeval tv;
|
||||
(void)gettimeofday(&tv);
|
||||
],
|
||||
msg="yes"
|
||||
,
|
||||
msg="no"
|
||||
)
|
||||
case $PLATFORM in
|
||||
*-*-mvs* ) msg="no" ;; # on OS/390 the compiler test doesn't work
|
||||
*-*-aix4* ) msg="no" ;; # on AIX the compiler test doesn't work
|
||||
*-*-isc* ) msg="no" ;; # on ISC the compiler test doesn't work
|
||||
esac
|
||||
if test ".$msg" = .yes; then
|
||||
AC_DEFINE(HAVE_GETTIMEOFDAY_ARGS1)
|
||||
fi
|
||||
AC_MSG_RESULT([$msg])
|
||||
|
||||
dnl # check for struct timespec
|
||||
AC_MSG_CHECKING(for struct timespec)
|
||||
cross_compile=no
|
||||
AC_TRY_COMPILE([
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
],[
|
||||
struct timespec ts;
|
||||
],
|
||||
msg="yes"
|
||||
,
|
||||
msg="no"
|
||||
)
|
||||
if test ".$msg" = .yes; then
|
||||
AC_DEFINE(HAVE_STRUCT_TIMESPEC)
|
||||
fi
|
||||
AC_MSG_RESULT([$msg])
|
||||
|
||||
dnl ##
|
||||
dnl ## MACHINE CONTEXT IMPLEMENTATION
|
||||
dnl ##
|
||||
|
@ -406,4 +277,3 @@ Makefile
|
|||
pth.h
|
||||
pth_acmac.h
|
||||
)
|
||||
|
||||
|
|
207
gst/cothreads/cothread-stack.c
Normal file
207
gst/cothreads/cothread-stack.c
Normal file
|
@ -0,0 +1,207 @@
|
|||
/* Pthread-friendly coroutines with pth
|
||||
* Copyright (C) 2001 Andy Wingo <wingo@pobox.com>
|
||||
*
|
||||
* cothread-stack.c: various methods of allocating cothread stacks
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* chunks can contain 1 or more blocks, each block contains one cothread stack */
|
||||
|
||||
enum cothread_attr_method
|
||||
{
|
||||
COTHREAD_ATTR_METHOD_MALLOC, /* cothread stacks on the heap, one block per chunk */
|
||||
COTHREAD_ATTR_METHOD_GTHREAD_STACK, /* cothread stacks within the current gthread's stack */
|
||||
COTHREAD_ATTR_METHOD_LINUXTHREADS, /* a hack that allows for linuxthreads compatibility */
|
||||
}
|
||||
|
||||
struct cothread_attr {
|
||||
enum cothread_attr_method method;
|
||||
int chunk_size;
|
||||
int blocks_per_chunk;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUXTHREADS
|
||||
static struct cothread_attr cothread_attr_default =
|
||||
{
|
||||
COTHREAD_ATTR_METHOD_LINUXTHREADS, /* use the linuxthreads hack */
|
||||
0x20000, /* 2 MB */
|
||||
8 /* for a stack size of 256 KB */
|
||||
}
|
||||
#else
|
||||
static struct cothread_attr cothread_attr_default =
|
||||
{
|
||||
COTHREAD_ATTR_METHOD_GTHREAD_STACK, /* this is what the old cothreads code does */
|
||||
0x10000, /* only 1 MB due the the FreeBSD defaults */
|
||||
8 /* for a stack size of 128 KB */
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct cothread_attr *_attr = NULL; /* set in cothread_init() */
|
||||
|
||||
enum cothread_block_state
|
||||
{
|
||||
COTHREAD_BLOCK_STATE_UNUSED=0,
|
||||
COTHREAD_BLOCK_STATE_IN_USE
|
||||
}
|
||||
|
||||
struct cothread_chunk {
|
||||
struct cothread_chunk *next;
|
||||
enum cothread_block_state *block_states;
|
||||
char *chunk;
|
||||
int size;
|
||||
int reserved_bottom;
|
||||
gboolean needs_free;
|
||||
}
|
||||
|
||||
/* size must be a power of two. */
|
||||
struct cothread_chunk*
|
||||
cothread_chunk_new (unsigned long size, gboolean allocate)
|
||||
{
|
||||
struct cothread_chunk *ret;
|
||||
char *sp = CURRENT_STACK_FRAME;
|
||||
|
||||
ret = g_new0 (struct cothread_chunk, 1);
|
||||
ret->block_states = g_new0 (enum cothread_block_state, _attr->blocks_per_chunk);
|
||||
|
||||
if (allocate) {
|
||||
if (!posix_memalign(&ret->chunk, size, size))
|
||||
g_error ("memalign operation failed");
|
||||
} else {
|
||||
/* if we don't allocate the chunk, we must already be in it. */
|
||||
|
||||
ret->chunk = (unsigned long) sp &~ (size - 1);
|
||||
#if PTH_STACK_GROWTH > 0
|
||||
ret->reserved_bottom = sp - ret->chunk;
|
||||
#else
|
||||
ret->reserved_bottom = sp + size - ret->chunk;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret->size = size;
|
||||
ret->needs_free = allocate;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cothread_stack_alloc_on_heap (char **low, char **high)
|
||||
{
|
||||
*low = g_malloc (_attr->chunk_size / _attr->blocks_per_chunk);
|
||||
*high = *low + sizeof (*low);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* cothread_stack_alloc_chunked:
|
||||
* @chunk: the chunk for the
|
||||
* Make a new cothread stack out of a chunk. Chunks are assumed to be aligned on
|
||||
* boundaries of _attr->chunk_size.
|
||||
*
|
||||
* Returns: the new cothread context
|
||||
*/
|
||||
/* we assume that the stack is aligned on _attr->chunk_size boundaries */
|
||||
static gboolean
|
||||
cothread_stack_alloc_chunked (struct cothread_chunk *chunk, char **low, char **high,
|
||||
(struct cothread_chunk*)(*chunk_new)(struct cothread_chunk*))
|
||||
{
|
||||
int block;
|
||||
struct cothread_chunk *walk, *last;
|
||||
|
||||
for (walk=chunk; walk; last=walk, walk=walk->next) {
|
||||
if (chunk->block_states[0] == COTHREAD_BLOCK_STATE_UNUSED) {
|
||||
chunk->block_states[0] = COTHREAD_BLOCK_STATE_IN_USE;
|
||||
#if PTH_STACK_GROWTH > 0
|
||||
*low = chunk->chunk + chunk->reserved_bottom;
|
||||
*high = chunk->chunk + chunk->chunk_size / _attr->blocks_per_chunk;
|
||||
#else
|
||||
*low = chunk->chunk + chunk->size * (chunk->nblocks - 1) / chunk->nblocks;
|
||||
*high = chunk->chunk + chunk->size - chunk->reserved_bottom;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (block = 1; block < _attr->blocks_per_chunk; block++) {
|
||||
if (chunk->block_states[block] == COTHREAD_BLOCK_STATE_UNUSED) {
|
||||
#if PTH_STACK_GROWTH > 0
|
||||
*low = chunk->chunk + chunk->size * (chunk->nblocks - block - 1) / chunk->nblocks;
|
||||
#else
|
||||
*low = chunk->chunk + chunk->size * (block - 1) / chunk->nblocks;
|
||||
#endif
|
||||
*high = *low + chunk->size / chunk->nblocks;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!chunk_new)
|
||||
return FALSE;
|
||||
else
|
||||
return cothread_stack_alloc_chunked (chunk_new (last), low, high, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cothread_stack_alloc_on_gthread_stack (char **low, char **high)
|
||||
{
|
||||
struct cothread_chunk *chunk = NULL;
|
||||
static GStaticPrivate chunk_key = G_STATIC_PRIVATE_INIT;
|
||||
|
||||
if (!(chunk = g_static_private_get(&chunk_key))) {
|
||||
chunk = cothread_chunk_new (_attr->size, FALSE);
|
||||
g_static_private_set (&chunk_key, chunk, cothread_chunk_free);
|
||||
}
|
||||
|
||||
return cothread_stack_alloc_chunked (chunk, low, high, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cothread_stack_alloc_linuxthreads (char **low, char **high)
|
||||
{
|
||||
struct cothread_chunk *chunk = NULL;
|
||||
static GStaticPrivate chunk_key = G_STATIC_PRIVATE_INIT;
|
||||
|
||||
if (!(chunk = g_static_private_get(&chunk_key))) {
|
||||
chunk = cothread_chunk_new (_attr->size, FALSE);
|
||||
g_static_private_set (&chunk_key, chunk, cothread_chunk_free);
|
||||
}
|
||||
|
||||
return cothread_stack_alloc_chunked (chunk, low, high, cothread_chunk_new_linuxthreads);
|
||||
}
|
||||
|
||||
struct cothread_chunk*
|
||||
cothread_chunk_new_linuxthreads (struct cothread_chunk* old)
|
||||
{
|
||||
struct cothread_chunk *new;
|
||||
void *pthread_descr;
|
||||
|
||||
new = cothread_chunk_new (_attr->chunk_size, TRUE);
|
||||
pthread_descr = __linuxthreads_self();
|
||||
#if PTH_STACK_GROWTH > 0
|
||||
/* we don't really know pthread_descr's size in this case, but we can be
|
||||
* conservative. it's normally 1K in the down-growing case, so we allocate 2K.
|
||||
*/
|
||||
new->reserved_bottom = 2048;
|
||||
memcpy(new->chunk, pthread_descr, 2048);
|
||||
#else
|
||||
new->reserved_bottom = ((unsigned long) pthread_descr | (_attr->chunk_size - 1)) - (unsigned long) pthread_descr;
|
||||
memcpy(new->chunk + new->size - new->reserved_bottom - 1, pthread_descr, new->reserved_bottom);
|
||||
#endif
|
||||
|
||||
old->next = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
|
|
@ -1,38 +1,5 @@
|
|||
/* LinuxThreads internal data structures */
|
||||
/* hacked for use with gstreamer by andy wingo <wingo@pobox.com> */
|
||||
|
||||
#include <bits/local_lim.h> /* PTHREAD_THREADS_MAX */
|
||||
#include <sys/types.h> /* _pthread_fastlock */
|
||||
|
||||
#ifndef CURRENT_STACK_FRAME
|
||||
#define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
|
||||
#endif /* CURRENT_STACK_FRAME */
|
||||
|
||||
#ifndef STACK_SIZE
|
||||
#define STACK_SIZE 0x200000 /* 2 M linuxthreads default stack size */
|
||||
#endif
|
||||
|
||||
typedef void * pthread_descr;
|
||||
|
||||
/* Global array of thread handles, used for validating a thread id
|
||||
and retrieving the corresponding thread descriptor. Also used for
|
||||
mapping the available stack segments. */
|
||||
|
||||
#pragma weak __pthread_handles
|
||||
extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX];
|
||||
|
||||
struct pthread_handle_struct {
|
||||
struct _pthread_fastlock h_lock; /* Fast lock for sychronized access */
|
||||
pthread_descr h_descr; /* Thread descriptor or NULL if invalid */
|
||||
char * h_bottom; /* Lowest address in the stack thread */
|
||||
};
|
||||
|
||||
typedef struct pthread_handle_struct * pthread_handle;
|
||||
|
||||
/* Return the handle corresponding to a thread id */
|
||||
|
||||
static inline pthread_handle thread_handle(pthread_t id)
|
||||
{
|
||||
return &__pthread_handles[id % PTHREAD_THREADS_MAX];
|
||||
}
|
||||
|
||||
#define STACK_SIZE 0x200000
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
/* essential headers */
|
||||
#include <sys/types.h> /* for ssize_t, off_t */
|
||||
#include <sys/signal.h> /* for sigset_t */
|
||||
@EXTRA_INCLUDE_SYS_SELECT_H@
|
||||
|
||||
/* essential values */
|
||||
#ifndef FALSE
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#define _PTH_P_H_
|
||||
|
||||
/* mandatory system headers */
|
||||
|
||||
#include <errno.h>
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -35,7 +38,6 @@
|
|||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -43,6 +45,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
*/
|
||||
|
||||
/* library version */
|
||||
#define _PTH_VERS_C_AS_HEADER_
|
||||
|
@ -58,48 +61,6 @@
|
|||
#include "pth_acdef.h"
|
||||
#include "pth_acmac.h"
|
||||
|
||||
/* optional system headers */
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_ERRNO_H
|
||||
#include <net/errno.h>
|
||||
#endif
|
||||
|
||||
/* dmalloc support */
|
||||
#ifdef PTH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
/* paths */
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
#endif
|
||||
#ifdef _PATH_BSHELL
|
||||
#define PTH_PATH_BINSH _PATH_BSHELL
|
||||
#else
|
||||
#define PTH_PATH_BINSH "/bin/sh"
|
||||
#endif
|
||||
|
||||
/* non-blocking flags */
|
||||
#ifdef O_NONBLOCK
|
||||
#define O_NONBLOCKING O_NONBLOCK
|
||||
#else
|
||||
#ifdef O_NDELAY
|
||||
#define O_NONBLOCKING O_NDELAY
|
||||
#else
|
||||
#ifdef FNDELAY
|
||||
#define O_NONBLOCKING FNDELAY
|
||||
#else
|
||||
#error "No O_NONBLOCK, O_NDELAY or FNDELAY flag available!"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* compiler happyness: avoid ``empty compilation unit'' problem */
|
||||
#define COMPILER_HAPPYNESS(name) \
|
||||
int __##name##_unit = 0;
|
||||
|
||||
/* generated contents */
|
||||
BEGIN_DECLARATION
|
||||
==#==
|
||||
|
|
|
@ -1,35 +1,7 @@
|
|||
#define __USE_GNU /* non-posix functions */
|
||||
#include <pthread.h>
|
||||
#undef __USE_GNU
|
||||
#include <stdio.h>
|
||||
#include "linuxthreads-internals.h"
|
||||
#include "linuxthreads.h"
|
||||
#include "pth_p.h"
|
||||
|
||||
/* this function is only really necessary to get the main thread's
|
||||
* pthread_descr, as the other threads store the pthread_descr (actually the
|
||||
* first member of struct _pthread_descr_struct, which points to itself for the
|
||||
* default (non-indirected) case) at the top of the stack. */
|
||||
static _pthread_descr linuxthreads_self()
|
||||
{
|
||||
pthread_mutexattr_t mutexattr;
|
||||
pthread_mutex_t mutex;
|
||||
_pthread_descr self;
|
||||
|
||||
pthread_mutexattr_init (&mutexattr);
|
||||
pthread_mutexattr_setkind_np (&mutexattr, PTHREAD_MUTEX_ERRORCHECK_NP);
|
||||
pthread_mutex_init (&mutex, &mutexattr);
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
self = mutex.__m_owner;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
|
||||
printf ("pthread_self: %d\n", pthread_self());
|
||||
printf ("descr: %p\n", self);
|
||||
printf ("*descr: %p\n", *(int*)self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pth_mctx_t main_context;
|
||||
int threadnum = 0;
|
||||
|
||||
|
@ -49,7 +21,7 @@ void *pthread (void *unused)
|
|||
pth_mctx_t ctx;
|
||||
_pthread_descr descr;
|
||||
|
||||
descr = linuxthreads_self();
|
||||
descr = __linuxthreads_self();
|
||||
printf ("sp: %p\n", sp);
|
||||
printf ("STACK_SIZE: %p\n", STACK_SIZE);
|
||||
printf ("sp | STACK_SIZE: 0x%x\n", (int) sp | STACK_SIZE );
|
||||
|
@ -84,7 +56,7 @@ int main (int argc, char *argv[])
|
|||
pthread_create (&tid, NULL, pthread, NULL);
|
||||
pthread_join (tid, NULL);
|
||||
|
||||
linuxthreads_self();
|
||||
__linuxthreads_self();
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue