Faster and modular getbits implementation.

Original commit message from CVS:
Faster and modular getbits implementation.
Fixed a bug in the audiosink that could lock up your box on bad MB.
Modified the plugins to use the new getbits functions.
This commit is contained in:
Wim Taymans 2000-09-07 20:35:15 +00:00
parent 7ccc2cf90b
commit 23540ccc52
14 changed files with 531 additions and 130 deletions

View file

@ -59,7 +59,7 @@ libgstinclude_HEADERS = \
gstxml.h \ gstxml.h \
cothreads.h cothreads.h
CFLAGS += -O2 -Wall CFLAGS += -g -O2 -Wall
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS) libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE) libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)

View file

@ -1,10 +1,10 @@
#include <pthread.h>
#include <sys/time.h> #include <sys/time.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <setjmp.h> #include <setjmp.h>
#include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) { cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s; cothread_state *s;
if (pthread_self() == 0) { printf("pthread_self() %ld\n",pthread_self());
//if (pthread_self() == 0) {
if (0) {
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE); s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
printf("new stack at %p\n",s);
} else { } else {
char *sp = CURRENT_STACK_FRAME; char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp & unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
s->ctx = ctx; s->ctx = ctx;
s->threadnum = ctx->nthreads; s->threadnum = ctx->nthreads;
s->flags = 0; s->flags = 0;
s->sp = (int *)(s + COTHREAD_STACKSIZE); s->sp = ((int *)s + COTHREAD_STACKSIZE);
ctx->threads[ctx->nthreads++] = s; ctx->threads[ctx->nthreads++] = s;
// printf("created cothread at %p\n",s); printf("created cothread at %p %p\n",s, s->sp);
return s; return s;
} }
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
ctx->threads[0]->argc = 0; ctx->threads[0]->argc = 0;
ctx->threads[0]->argv = NULL; ctx->threads[0]->argv = NULL;
ctx->threads[0]->flags = COTHREAD_STARTED; ctx->threads[0]->flags = COTHREAD_STARTED;
ctx->threads[0]->sp = CURRENT_STACK_FRAME; ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0; ctx->threads[0]->pc = 0;
// fprintf(stderr,"0th thread is at %p\n",ctx->threads[0]); fprintf(stderr,"0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
// we consider the initiating process to be cothread 0 // we consider the initiating process to be cothread 0
ctx->nthreads = 1; ctx->nthreads = 1;
@ -91,11 +94,13 @@ void cothread_stub() {
cothread_context *ctx = pthread_getspecific(_cothread_key); cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current]; register cothread_state *thread = ctx->threads[ctx->current];
printf("cothread_stub() entered\n");
thread->flags |= COTHREAD_STARTED; thread->flags |= COTHREAD_STARTED;
thread->func(thread->argc,thread->argv); if (thread->func)
thread->func(thread->argc,thread->argv);
thread->flags &= ~COTHREAD_STARTED; thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0; thread->pc = 0;
// printf("uh, yeah, we shouldn't be here, but we should deal anyway\n"); //printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
} }
void cothread_switch(cothread_state *thread) { void cothread_switch(cothread_state *thread) {
@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) {
// find the number of the thread to switch to // find the number of the thread to switch to
ctx->current = thread->threadnum; ctx->current = thread->threadnum;
// fprintf(stderr,"about to switch to thread #%d\n",ctx->current); fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
/* save the current stack pointer, frame pointer, and pc */ /* save the current stack pointer, frame pointer, and pc */
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp"); __asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
return; return;
enter = 1; enter = 1;
fprintf(stderr,"set stack to %p\n", thread->sp);
/* restore stack pointer and other stuff of new cothread */ /* restore stack pointer and other stuff of new cothread */
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
if (thread->flags & COTHREAD_STARTED) { if (thread->flags & COTHREAD_STARTED) {
fprintf(stderr,"in thread \n");
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
// switch to it // switch to it
longjmp(thread->jmp,1); longjmp(thread->jmp,1);
} else { } else {
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
// start it // start it
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub)); __asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
} }

View file

@ -25,6 +25,8 @@
#include <sys/soundcard.h> #include <sys/soundcard.h>
#include <unistd.h> #include <unistd.h>
//#define DEBUG_ENABLED
#include <gstaudiosink.h> #include <gstaudiosink.h>
#include <gst/meta/audioraw.h> #include <gst/meta/audioraw.h>
@ -184,6 +186,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL); g_return_if_fail(buf != NULL);
/* this has to be an audio buffer */ /* this has to be an audio buffer */
// g_return_if_fail(((GstMeta *)buf->meta)->type != // g_return_if_fail(((GstMeta *)buf->meta)->type !=
//gst_audiosink_type_audio); //gst_audiosink_type_audio);
@ -212,6 +215,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF], gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF],
audiosink); audiosink);
if (GST_BUFFER_DATA(buf) != NULL) { if (GST_BUFFER_DATA(buf) != NULL) {
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard"); gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
//g_print("audiosink: writing to soundcard\n"); //g_print("audiosink: writing to soundcard\n");
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
if (!audiosink->mute) { if (!audiosink->mute) {
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink)); gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace); ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
DEBUG("audiosink: (%d bytes buffer)\n", ospace.bytes); DEBUG("audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, audiosink->fd, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf));
write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
//write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
} }
} }
} }
@ -288,7 +293,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
g_print("audiosink: attempting to open sound device\n"); g_print("audiosink: attempting to open sound device\n");
/* first try to open the sound card */ /* first try to open the sound card */
sink->fd = open("/dev/dsp",O_RDWR); sink->fd = open("/dev/dsp",O_WRONLY);
/* if we have it, set the default parameters and go have fun */ /* if we have it, set the default parameters and go have fun */
if (sink->fd > 0) { if (sink->fd > 0) {
@ -306,7 +311,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n");
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n");
g_print("audiosink: opened audio\n"); g_print("audiosink: opened audio with fd=%d\n", sink->fd);
GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN); GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN);
return TRUE; return TRUE;
} }

View file

@ -603,8 +603,8 @@ void gst_bin_iterate_func(GstBin *bin) {
if (bin->need_cothreads) { if (bin->need_cothreads) {
// all we really have to do is switch to the first child // all we really have to do is switch to the first child
// FIXME this should be lots more intelligent about where to start // FIXME this should be lots more intelligent about where to start
// g_print("** in gst_bin_iterate_func()==================================%s\n", //g_print("** in gst_bin_iterate_func()==================================%s\n",
// gst_element_get_name(GST_ELEMENT(bin->children->data))); // gst_element_get_name(GST_ELEMENT(bin->children->data)));
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate); cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
} else { } else {
entries = bin->entries; entries = bin->entries;

View file

@ -5,3 +5,4 @@ Makefile.in
*.la *.la
.deps .deps
.libs .libs
gbtest

View file

@ -2,14 +2,19 @@ filterdir = $(libdir)/gst
filter_LTLIBRARIES = libgstgetbits.la filter_LTLIBRARIES = libgstgetbits.la
libgstgetbits_la_SOURCES = gstgetbits.c gstgetbits_inl.h libgstgetbits_la_SOURCES = gstgetbits.c gstgetbits_inl.h gstgetbits_i386.s
libgstgetbitsincludedir = $(includedir)/gst/libs/gstgetbits libgstgetbitsincludedir = $(includedir)/gst/libs/gstgetbits
libgstgetbitsinclude_HEADERS = gstgetbits.h libgstgetbitsinclude_HEADERS = gstgetbits.h
noinst_HEADERS = gstgetbits.h gstgetbits_inl.h noinst_HEADERS = gstgetbits.h gstgetbits_inl.h
CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math bin_PROGRAMS = gbtest
gbtest_SOURCES = gbtest.c
gbtest_LDADD = libgstgetbits.la
CFLAGS += -Wall -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la

94
libs/getbits/gbtest.c Normal file
View file

@ -0,0 +1,94 @@
#include <stdlib.h>
#include "gstgetbits.h"
char *print_bits(unsigned long bits,int size) {
char *ret = (char *)malloc(size+1);
int i;
ret[size] = 0;
for (i=0;i<size;i++) {
if (bits & (1<<i))
ret[(size-1)-i] = '1';
else
ret[(size-1)-i] = '0';
}
return ret;
}
static unsigned char testbuffer[] =
{
0x11, 0x22, 0x44, 0x88, 0xCC, 0xEE,0xFF,0x11
};
void empty(gst_getbits_t *gb, void *data) {
printf("buffer empty\n");
gst_getbits_newbuf(gb,(unsigned char *)testbuffer, 7);
}
int main(int argc,char *argv[]) {
gst_getbits_t gb;
int i, j;
int bits;
gst_getbits_init(&gb, NULL, NULL);
gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7);
for (i=0;i<7;i++) {
for (j=0;j<8;j++) {
printf("%lu",gst_getbits2(&gb));
gst_backbitsn(&gb, 1);
}
printf(" = %01x\n", testbuffer[i]);
}
gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000011 %lu\n",bits, gb.bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000022 %lu\n",bits, gb.bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000044 %lu\n",bits, gb.bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000088 %lu\n",bits, gb.bits);
bits = gst_getbits6(&gb);
printf("%08x <-> 00000033 %lu\n",bits, gb.bits);
gst_backbitsn(&gb, 16);
bits = gst_getbits10(&gb);
printf("%08x <-> 00000088 \n",bits);
gst_getbits_newbuf(&gb,(unsigned char *)testbuffer, 7);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000011 \n",bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000022 \n",bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000044 \n",bits);
bits = gst_getbits6(&gb);
printf("%08x <-> 00000022 \n",bits);
gst_backbitsn(&gb, 19);
bits = gst_getbits19(&gb);
printf("%08x <-> 00009122 \n",bits);
bits = gst_getbits10(&gb);
printf("%08x <-> 000000cc \n",bits);
gst_backbitsn(&gb, 8);
gst_backbitsn(&gb, 19);
gst_backbitsn(&gb, 8);
bits = gst_getbits19(&gb);
printf("%08x <-> 00012244 \n",bits);
bits = gst_getbits8(&gb);
printf("%08x <-> 00000088 \n",bits);
return 0;
}

View file

@ -1,6 +1,38 @@
#include <byteswap.h> #include <glib.h>
#include "gstgetbits.h" #include "gstgetbits.h"
extern unsigned long _gst_get1bit_i386(gst_getbits_t *gb, unsigned long bits);
extern unsigned long _gst_getbits_i386(gst_getbits_t *gb, unsigned long bits);
extern unsigned long _gst_getbits_fast_i386(gst_getbits_t *gb, unsigned long bits);
extern unsigned long _gst_showbits_i386(gst_getbits_t *gb, unsigned long bits);
extern void _gst_flushbits_i386(gst_getbits_t *gb, unsigned long bits);
extern void _gst_getbits_back_i386(gst_getbits_t *gb, unsigned long bits);
//#define DEBUG_ENABLED
#ifdef DEBUG_ENABLED
#define DEBUG(format, args...) g_print("DEBUG:(%d) " format, getpid() , ##args)
#else
#define DEBUG(format, args...)
#endif
#ifdef WORDS_BIGENDIAN
# define swab32(x) (x)
#else
# if defined (__i386__)
# define swab32(x) __i386_swab32(x)
static inline const guint32 __i386_swab32(guint32 x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
}
# else
# define swab32(x)\
((((guint8*)&x)[0] << 24) | (((guint8*)&x)[1] << 16) | \
(((guint8*)&x)[2] << 8) | (((guint8*)&x)[3]))
# endif
#endif
unsigned long gst_getbits_nBitMask[] = { unsigned long gst_getbits_nBitMask[] = {
0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
@ -35,7 +67,7 @@ unsigned long _getbits_64_minus_index[] = {
this isn't as cycle-efficient, due to the simple fact that I must call this isn't as cycle-efficient, due to the simple fact that I must call
emms() at the end. all state must be kept in *gb, not in registers */ emms() at the end. all state must be kept in *gb, not in registers */
unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) { unsigned long _gst_getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
signed long remaining; signed long remaining;
unsigned long result; unsigned long result;
@ -63,9 +95,9 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
remaining += 64; remaining += 64;
/* grab the first 32 bits from the buffer and swap them around */ /* grab the first 32 bits from the buffer and swap them around */
dword1 = bswap_32(*(gb->ptr-8)); dword1 = swab32(*(gb->ptr-8));
/* grab the second 32 bits, swap */ /* grab the second 32 bits, swap */
dword2 = bswap_32(*(gb->ptr-4)); dword2 = swab32(*(gb->ptr-4));
/* put second dword in mm4 */ /* put second dword in mm4 */
movd_m2r(dword2,mm4); movd_m2r(dword2,mm4);
@ -130,96 +162,121 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
} }
#endif /* HAVE_LIBMMX */ #endif /* HAVE_LIBMMX */
unsigned long getbits_int(gst_getbits_t *gb,unsigned long bits) { unsigned long _gst_getbits_int_cb(gst_getbits_t *gb, unsigned long bits) {
int remaining; int result;
int result = 0; int bitsleft;
if (bits == 0) { //printf("gst_getbits%lu %ld %p %08x\n", bits, gb->bits, gb->ptr, gb->dword);
// fprintf(stderr,"getbits(0) = 0\n");
return 0; if (!bits) return 0;
}
gb->bits -= bits;
result = gb->dword >> (32-bits);
if (gb->bits < 0) {
remaining = gb->bits - bits;
if (remaining < 0) {
/* how many bits are left to get? */
remaining = -remaining;
// printf("have to get %d more bits from next dword\n",remaining);
/* move what's left over to accomodate the new stuff */
result = gb->dword >> (32 - bits);
// printf("have \t\t%s from previous dword\n",print_bits(result));
/* get the new word into the buffer */
// fprintf(stderr,"getbits: incrementing %p by 4\n",gb->ptr);
gb->ptr += 4; gb->ptr += 4;
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
// gb->dword = *((unsigned char *)(gb->ptr)) << 24 | bitsleft = (gb->endptr - gb->ptr)*8;
// *((unsigned char *)(gb->ptr)+1) << 16 | bits = -gb->bits;
// *((unsigned char *)(gb->ptr)+2) << 8 | gb->bits += (bitsleft>32? 32 : bitsleft);
// *((unsigned char *)(gb->ptr)+3);
// gb->dword = *((unsigned long *)(gb->ptr)); if (gb->endptr <= gb->ptr) {
gb->bits = 32; (gb->callback)(gb, gb->data);
// fprintf(stderr,"got new dword %08x\n",gb->dword); gb->bits -= bits;
/* & in the right number of bits */ }
result |= (gb->dword >> (32 - remaining)); gb->dword = swab32(*((unsigned long *)(gb->ptr)));
/* shift the buffer over */
gb->dword <<= remaining; result |= (gb->dword >> (32-bits));
/* record how many bits are left */
gb->bits -= remaining;
} else {
result = gb->dword >> (32 - bits);
gb->dword <<= bits;
gb->bits -= bits;
// printf("have %d bits left\n",gb->bits);
} }
// printf("have \t\t%s left\n",print_bits(gb->dword)); gb->dword <<= bits;
// fprintf(stderr,"getbits.c:getbits(%ld) = %d\n",bits,result);
return result; return result;
} }
void getbits_back_int(gst_getbits_t *gb,unsigned long bits) { void _gst_getbits_back_int(gst_getbits_t *gb, unsigned long bits) {
fprintf(stderr,"getbits.c:getbits_back(%lu)\n",bits); gb->bits -= bits;
// moving within the same dword... gb->ptr += (gb->bits>>3);
if ((bits + gb->bits) <= 32) { gb->bits &= 0x7;
fprintf(stderr,"moving back %lu bits in the same dword\n",bits);
gb->bits += bits;
// otherwise we're going to have move the pointer (ick)
} else {
// rare case where we're moving a multiple of 32 bits...
if ((bits % 32) == 0) {
fprintf(stderr,"moving back exactly %lu dwords\n",bits/32);
gb->ptr -= (bits / 8);
// we have to both shift bits and the pointer (NOOOOOOO!)
} else {
// strip off the first dword
bits -= (32 - gb->bits);
gb->ptr -= 4;
// now strip off as many others as necessary
gb->ptr -= 4 * (bits/32);
// and set the bits to what's left
gb->bits = bits % 32;
fprintf(stderr,"moved back %lu bytes to %p\n",4 * ((bits/32)+1),gb->ptr);
}
}
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
fprintf(stderr,"orignal new loaded word is %08lx\n",gb->dword);
gb->dword <<= (32 - gb->bits);
fprintf(stderr,"shifted (by %lu) word is %08lx\n",gb->bits,gb->dword);
} }
void getbits_byteback_int(gst_getbits_t *gb,unsigned long bytes) { unsigned long _gst_showbits_int(gst_getbits_t *gb, unsigned long bits) {
fprintf(stderr,"getbits.c:getbits_byteback(%lu)\n",bytes); unsigned long rval;
getbits_back_int(gb,bytes*8);
gb->bits = gb->bits & ~0x07; if (bits == 0) return 0;
rval = swab32(*((unsigned long *)(gb->ptr)));
rval <<= gb->bits;
rval >>= (32-bits);
DEBUG("showbits%d, %08x\n", bits, rval);
return rval;
} }
int getbits_offset(gst_getbits_t *gb) { unsigned long _gst_getbyte(gst_getbits_t *gb, unsigned long bits) {
fprintf(stderr,"getbits.c:getbits_offset() = %lu\n",gb->bits % 8); return *gb->ptr++;
return gb->bits % 8; }
unsigned long _gst_get1bit_int(gst_getbits_t *gb, unsigned long bits) {
unsigned char rval;
rval = *gb->ptr << gb->bits;
gb->bits++;
gb->ptr += (gb->bits>>3);
gb->bits &= 0x7;
DEBUG("getbits%d, %08x\n", bits, rval);
return rval>>7;
}
unsigned long _gst_getbits_fast_int(gst_getbits_t *gb, unsigned long bits) {
unsigned long rval;
rval = (unsigned char) (gb->ptr[0] << gb->bits);
rval |= ((unsigned int) gb->ptr[1] << gb->bits)>>8;
rval <<= bits;
rval >>= 8;
gb->bits += bits;
gb->ptr += (gb->bits>>3);
gb->bits &= 0x7;
DEBUG("getbits%d, %08x\n", bits, rval);
return rval;
}
unsigned long _gst_getbits_int(gst_getbits_t *gb, unsigned long bits) {
unsigned long rval;
if (bits == 0) return 0;
rval = swab32(*((unsigned long *)(gb->ptr)));
rval <<= gb->bits;
gb->bits += bits;
rval >>= (32-bits);
gb->ptr += (gb->bits>>3);
gb->bits &= 0x7;
DEBUG("getbits%d, %08x\n", bits, rval);
return rval;
}
void _gst_flushbits_int(gst_getbits_t *gb, unsigned long bits) {
gb->bits += bits;
gb->ptr += (gb->bits>>3);
gb->bits &= 0x7;
DEBUG("flushbits%d\n", bits);
} }
/* initialize the getbits structure with the proper getbits func */ /* initialize the getbits structure with the proper getbits func */
void getbits_init(gst_getbits_t *gb) { void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data) {
gb->ptr = NULL; gb->ptr = NULL;
gb->bits = 0; gb->bits = 0;
gb->callback = callback;
gb->data = data;
#ifdef HAVE_LIBMMX #ifdef HAVE_LIBMMX
if (1) { if (1) {
@ -229,18 +286,30 @@ void getbits_init(gst_getbits_t *gb) {
} else } else
#endif /* HAVE_LIBMMX */ #endif /* HAVE_LIBMMX */
{ {
gb->getbits = getbits_int; if (gb->callback) {
gb->backbits = getbits_back_int; gb->getbits = _gst_getbits_int_cb;
gb->backbytes = getbits_byteback_int; gb->showbits = _gst_showbits_int;
gb->flushbits = _gst_flushbits_int;
gb->backbits = _gst_getbits_back_int;
}
else {
gb->get1bit = _gst_get1bit_i386;
gb->getbits = _gst_getbits_i386;
gb->getbits_fast = _gst_getbits_fast_i386;
gb->getbyte = _gst_getbyte;
gb->show1bit = _gst_showbits_i386;
gb->showbits = _gst_showbits_i386;
gb->flushbits = _gst_flushbits_i386;
gb->backbits = _gst_getbits_back_i386;
}
} }
} }
/* set up the getbits structure with a new buffer */ /* set up the getbits structure with a new buffer */
void getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer) { void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer, unsigned long len) {
gb->ptr = buffer - 4; gb->ptr = buffer;
// fprintf(stderr,"setting ptr to %p\n",gb->ptr); gb->endptr = buffer+len;
gb->bits = 0; gb->bits = 0;
gb->dword = 0;
#ifdef HAVE_LIBMMX #ifdef HAVE_LIBMMX
// gb->qword = 0; // gb->qword = 0;
#endif /* HAVE_LIBMMX */ #endif /* HAVE_LIBMMX */

View file

@ -16,6 +16,7 @@
#endif /* HAVE_LIBSSE */ #endif /* HAVE_LIBSSE */
typedef struct _gst_getbits_t gst_getbits_t; typedef struct _gst_getbits_t gst_getbits_t;
typedef void (*GstGetbitsCallback) (gst_getbits_t *gb, void *data);
/* breaks in structure show alignment on quadword boundaries */ /* breaks in structure show alignment on quadword boundaries */
/* FIXME: need to find out how to force GCC to align this to octwords */ /* FIXME: need to find out how to force GCC to align this to octwords */
@ -28,9 +29,17 @@ struct _gst_getbits_t {
unsigned long dword; unsigned long dword;
unsigned long temp; unsigned long temp;
unsigned long (*getbits)(gst_getbits_t *gb,unsigned long bits); /* dword */ GstGetbitsCallback callback;
void (*backbits)(gst_getbits_t *gb,unsigned long bits); /* dword */ void *data;
void (*backbytes)(gst_getbits_t *gb,unsigned long bytes); /* dword */
unsigned long (*get1bit)(gst_getbits_t *gb, unsigned long bits);
unsigned long (*getbits)(gst_getbits_t *gb, unsigned long bits);
unsigned long (*getbits_fast)(gst_getbits_t *gb, unsigned long bits);
unsigned long (*getbyte)(gst_getbits_t *gb, unsigned long bits);
unsigned long (*show1bit)(gst_getbits_t *gb, unsigned long bits);
unsigned long (*showbits)(gst_getbits_t *gb, unsigned long bits);
void (*flushbits)(gst_getbits_t *gb, unsigned long bits);
void (*backbits)(gst_getbits_t *gb, unsigned long bits);
#ifdef HAVE_LIBMMX #ifdef HAVE_LIBMMX
mmx_t qword; /* qword */ mmx_t qword; /* qword */
@ -42,18 +51,95 @@ struct _gst_getbits_t {
}; };
#define GST_GETBITS_INLINE
#ifdef GST_GETBITS_INLINE #ifdef GST_GETBITS_INLINE
#include "gstgetbits_inl.h" #include "gstgetbits_inl.h"
#else #else
void gst_getbits_init(gst_getbits_t *gb); void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data);
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer); void gst_getbits_newbuf(gst_getbits_t *gb, unsigned char *buffer, unsigned long len);
#define getbits(gb,bits) (((gb)->getbits)(gb,bits)) #define gst_getbits_bitoffset(gb) \
#define getbits_back(gb,bits) (((gb)->backbits)(gb,bits)) ( \
#define getbits_back_bytes(gb,bytes) (((gb)->backbytes)(gb,bytes)) (-(gb)->bits)&0x7 \
)
#define gst_getbits_align_byte(gb)
#define gst_getbits_bufferpos(gb) ((gb)->ptr)
#define gst_getbits_bytesleft(gb) ((gb)->endptr - (gb)->ptr)
#define gst_getbits_bitsleft(gb) (((gb)->endptr - (gb)->ptr)*8 - ((-(gb)->bits)&0x7))
#define gst_get1bit(gb) (((gb)->get1bit)(gb, 1))
#define gst_getbitsX(gb,bits) (((gb)->getbits)(gb,bits))
#define gst_getbits_fastX(gb,bits) (((gb)->getbits_fast)(gb,bits))
#define gst_show1bit(gb,bits) (((gb)->show1bit)(gb,bits))
#define gst_showbitsX(gb,bits) (((gb)->showbits)(gb,bits))
#define gst_flushbitsX(gb,bits) (((gb)->flushbits)(gb,bits))
#define gst_backbitsX(gb,bits) (((gb)->backbits)(gb,bits))
#define gst_getbyte(gb) (((gb)->getbyte)(gb,8))
#define gst_getbits_fastn(gb,n) gst_getbits_fastX(gb, n)
#define gst_getbitsn(gb,n) gst_getbitsX(gb, n)
#define gst_getbits1(gb) gst_get1bit(gb)
#define gst_getbits2(gb) gst_getbits_fastX(gb, 2)
#define gst_getbits3(gb) gst_getbits_fastX(gb, 3)
#define gst_getbits4(gb) gst_getbits_fastX(gb, 4)
#define gst_getbits5(gb) gst_getbits_fastX(gb, 5)
#define gst_getbits6(gb) gst_getbits_fastX(gb, 6)
#define gst_getbits7(gb) gst_getbits_fastX(gb, 7)
#define gst_getbits8(gb) gst_getbits_fastX(gb, 8)
#define gst_getbits9(gb) gst_getbits_fastX(gb, 9)
#define gst_getbits10(gb) gst_getbitsX(gb, 10)
#define gst_getbits11(gb) gst_getbitsX(gb, 11)
#define gst_getbits12(gb) gst_getbitsX(gb, 12)
#define gst_getbits13(gb) gst_getbitsX(gb, 13)
#define gst_getbits14(gb) gst_getbitsX(gb, 14)
#define gst_getbits15(gb) gst_getbitsX(gb, 15)
#define gst_getbits16(gb) gst_getbitsX(gb, 16)
#define gst_getbits17(gb) gst_getbitsX(gb, 17)
#define gst_getbits18(gb) gst_getbitsX(gb, 18)
#define gst_getbits19(gb) gst_getbitsX(gb, 19)
#define gst_getbits20(gb) gst_getbitsX(gb, 20)
#define gst_getbits21(gb) gst_getbitsX(gb, 21)
#define gst_getbits22(gb) gst_getbitsX(gb, 22)
#define gst_getbits23(gb) gst_getbitsX(gb, 23)
#define gst_showbitsn(gb,n) gst_showbitsX(gb, n)
#define gst_showbits1(gb) gst_show1bit(gb, 1)
#define gst_showbits2(gb) gst_showbitsX(gb, 2)
#define gst_showbits3(gb) gst_showbitsX(gb, 3)
#define gst_showbits4(gb) gst_showbitsX(gb, 4)
#define gst_showbits5(gb) gst_showbitsX(gb, 5)
#define gst_showbits6(gb) gst_showbitsX(gb, 6)
#define gst_showbits7(gb) gst_showbitsX(gb, 7)
#define gst_showbits8(gb) gst_showbitsX(gb, 8)
#define gst_showbits9(gb) gst_showbitsX(gb, 9)
#define gst_showbits10(gb) gst_showbitsX(gb, 10)
#define gst_showbits11(gb) gst_showbitsX(gb, 11)
#define gst_showbits12(gb) gst_showbitsX(gb, 12)
#define gst_showbits13(gb) gst_showbitsX(gb, 13)
#define gst_showbits14(gb) gst_showbitsX(gb, 14)
#define gst_showbits15(gb) gst_showbitsX(gb, 15)
#define gst_showbits16(gb) gst_showbitsX(gb, 16)
#define gst_showbits17(gb) gst_showbitsX(gb, 17)
#define gst_showbits18(gb) gst_showbitsX(gb, 18)
#define gst_showbits19(gb) gst_showbitsX(gb, 19)
#define gst_showbits20(gb) gst_showbitsX(gb, 20)
#define gst_showbits21(gb) gst_showbitsX(gb, 21)
#define gst_showbits22(gb) gst_showbitsX(gb, 22)
#define gst_showbits23(gb) gst_showbitsX(gb, 23)
#define gst_showbits24(gb) gst_showbitsX(gb, 24)
#define gst_showbits32(gb) gst_showbitsX(gb, 32)
#define gst_flushbitsn(gb,n) gst_flushbitsX(gb, n)
#define gst_flushbits32(gb) gst_flushbitsX(gb, 32)
#define gst_backbitsn(gb,n) gst_backbitsX(gb, n)
#define gst_backbits24(gb) gst_backbitsX(gb, 24)
#endif #endif
#endif /* __GST_GETBITS_H__ */ #endif /* __GST_GETBITS_H__ */

View file

@ -0,0 +1,115 @@
.p2align 4,,7
.globl _gst_getbits_i386
.type _gst_getbits_i386,@function
_gst_getbits_i386:
cmpl $0,8(%esp)
jne .L39
xorl %eax,%eax
ret
.L39:
movl 4(%esp),%edx
movl (%edx),%ecx
movl (%ecx),%eax
bswap %eax
movl 16(%edx),%ecx
shll %cl, %eax
movl 8(%esp),%ecx
addl %ecx, 16(%edx)
negl %ecx
addl $32,%ecx
shrl %cl, %eax
movl 16(%edx),%ecx
sarl $3,%ecx
addl %ecx,(%edx)
andl $7,16(%edx)
ret
.p2align 4,,7
.globl _gst_getbits_fast_i386
.type _gst_getbits_fast_i386,@function
_gst_getbits_fast_i386:
movl 4(%esp),%edx
movl (%edx),%ecx
movzbl 1(%ecx),%eax
movb (%ecx), %ah
movl 16(%edx),%ecx
shlw %cl, %ax
movl 8(%esp),%ecx
addl %ecx, 16(%edx)
negl %ecx
addl $16,%ecx
shrl %cl, %eax
movl 16(%edx),%ecx
sarl $3,%ecx
addl %ecx,(%edx)
andl $7,16(%edx)
ret
.p2align 4,,7
.globl _gst_get1bit_i386
.type _gst_get1bit_i386,@function
_gst_get1bit_i386:
movl 4(%esp),%edx
movl (%edx),%ecx
movzbl (%ecx),%eax
movl 16(%edx),%ecx
incl %ecx
rolb %cl, %al
andb $1, %al
movl %ecx, 16(%edx)
andl $7,16(%edx)
sarl $3,%ecx
addl %ecx,(%edx)
ret
.p2align 4,,7
.globl _gst_showbits_i386
.type _gst_showbits_i386,@function
_gst_showbits_i386:
cmpl $0,8(%esp)
jne .L40
xorl %eax,%eax
ret
.L40:
movl 4(%esp),%edx
movl (%edx),%ecx
movl (%ecx), %eax
bswap %eax
movl 16(%edx),%ecx
shll %cl, %eax
movl 8(%esp),%ecx
negl %ecx
addl $32,%ecx
shrl %cl, %eax
ret
.p2align 4,,7
.globl _gst_flushbits_i386
.type _gst_flushbits_i386,@function
_gst_flushbits_i386:
movl 4(%esp),%ecx
movl 16(%ecx),%eax
addl 8(%esp),%eax
movl %eax, %edx
sarl $3,%eax
addl %eax,(%ecx)
andl $7, %edx
movl %edx, 16(%ecx)
ret
.p2align 4,,7
.globl _gst_getbits_back_i386
.type _gst_getbits_back_i386,@function
_gst_getbits_back_i386:
movl 4(%esp),%edx
movl 16(%edx),%ecx
subl 8(%esp),%ecx
movl %ecx, %eax
sarl $3,%ecx
addl %ecx,(%edx)
andl $7,%eax
movl %eax, 16(%edx)
ret

View file

@ -93,7 +93,7 @@
/* External declarations for bitstream i/o operations. */ /* External declarations for bitstream i/o operations. */
extern unsigned long gst_getbits_nBitMask[]; extern unsigned long gst_getbits_nBitMask[];
#define gst_getbits_init(gb) #define gst_getbits_init(gb, callback, data)
#define gst_getbits_newbuf(gb, buffer, len) \ #define gst_getbits_newbuf(gb, buffer, len) \
{ \ { \

View file

@ -25,6 +25,8 @@
#include <sys/soundcard.h> #include <sys/soundcard.h>
#include <unistd.h> #include <unistd.h>
//#define DEBUG_ENABLED
#include <gstaudiosink.h> #include <gstaudiosink.h>
#include <gst/meta/audioraw.h> #include <gst/meta/audioraw.h>
@ -184,6 +186,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL); g_return_if_fail(buf != NULL);
/* this has to be an audio buffer */ /* this has to be an audio buffer */
// g_return_if_fail(((GstMeta *)buf->meta)->type != // g_return_if_fail(((GstMeta *)buf->meta)->type !=
//gst_audiosink_type_audio); //gst_audiosink_type_audio);
@ -212,6 +215,7 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF], gtk_signal_emit(GTK_OBJECT(audiosink),gst_audiosink_signals[SIGNAL_HANDOFF],
audiosink); audiosink);
if (GST_BUFFER_DATA(buf) != NULL) { if (GST_BUFFER_DATA(buf) != NULL) {
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard"); gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
//g_print("audiosink: writing to soundcard\n"); //g_print("audiosink: writing to soundcard\n");
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
if (!audiosink->mute) { if (!audiosink->mute) {
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink)); gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace); ioctl(audiosink->fd,SNDCTL_DSP_GETOSPACE,&ospace);
DEBUG("audiosink: (%d bytes buffer)\n", ospace.bytes); DEBUG("audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, audiosink->fd, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf));
write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); write(audiosink->fd,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
//write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf));
} }
} }
} }
@ -288,7 +293,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
g_print("audiosink: attempting to open sound device\n"); g_print("audiosink: attempting to open sound device\n");
/* first try to open the sound card */ /* first try to open the sound card */
sink->fd = open("/dev/dsp",O_RDWR); sink->fd = open("/dev/dsp",O_WRONLY);
/* if we have it, set the default parameters and go have fun */ /* if we have it, set the default parameters and go have fun */
if (sink->fd > 0) { if (sink->fd > 0) {
@ -306,7 +311,7 @@ static gboolean gst_audiosink_open_audio(GstAudioSink *sink) {
if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n");
if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n");
if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n");
g_print("audiosink: opened audio\n"); g_print("audiosink: opened audio with fd=%d\n", sink->fd);
GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN); GST_FLAG_SET(sink,GST_AUDIOSINK_OPEN);
return TRUE; return TRUE;
} }

View file

@ -1,10 +1,10 @@
#include <pthread.h>
#include <sys/time.h> #include <sys/time.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <setjmp.h> #include <setjmp.h>
#include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
cothread_state *cothread_create(cothread_context *ctx) { cothread_state *cothread_create(cothread_context *ctx) {
cothread_state *s; cothread_state *s;
if (pthread_self() == 0) { printf("pthread_self() %ld\n",pthread_self());
//if (pthread_self() == 0) {
if (0) {
s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE); s = (cothread_state *)malloc(sizeof(int) * COTHREAD_STACKSIZE);
printf("new stack at %p\n",s);
} else { } else {
char *sp = CURRENT_STACK_FRAME; char *sp = CURRENT_STACK_FRAME;
unsigned long *stack_end = (unsigned long *)((unsigned long)sp & unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
s->ctx = ctx; s->ctx = ctx;
s->threadnum = ctx->nthreads; s->threadnum = ctx->nthreads;
s->flags = 0; s->flags = 0;
s->sp = (int *)(s + COTHREAD_STACKSIZE); s->sp = ((int *)s + COTHREAD_STACKSIZE);
ctx->threads[ctx->nthreads++] = s; ctx->threads[ctx->nthreads++] = s;
// printf("created cothread at %p\n",s); printf("created cothread at %p %p\n",s, s->sp);
return s; return s;
} }
@ -56,7 +59,7 @@ cothread_context *cothread_init() {
if (_cothread_key == -1) { if (_cothread_key == -1) {
if (pthread_key_create(&_cothread_key,NULL) != 0) { if (pthread_key_create(&_cothread_key,NULL) != 0) {
perror("pthread_key_create"); perror("pthread_key_create");
return; return NULL;
} }
} }
pthread_setspecific(_cothread_key,ctx); pthread_setspecific(_cothread_key,ctx);
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
ctx->threads[0]->argc = 0; ctx->threads[0]->argc = 0;
ctx->threads[0]->argv = NULL; ctx->threads[0]->argv = NULL;
ctx->threads[0]->flags = COTHREAD_STARTED; ctx->threads[0]->flags = COTHREAD_STARTED;
ctx->threads[0]->sp = CURRENT_STACK_FRAME; ctx->threads[0]->sp = (int *)CURRENT_STACK_FRAME;
ctx->threads[0]->pc = 0; ctx->threads[0]->pc = 0;
// fprintf(stderr,"0th thread is at %p\n",ctx->threads[0]); fprintf(stderr,"0th thread is at %p %p\n",ctx->threads[0], ctx->threads[0]->sp);
// we consider the initiating process to be cothread 0 // we consider the initiating process to be cothread 0
ctx->nthreads = 1; ctx->nthreads = 1;
@ -91,11 +94,13 @@ void cothread_stub() {
cothread_context *ctx = pthread_getspecific(_cothread_key); cothread_context *ctx = pthread_getspecific(_cothread_key);
register cothread_state *thread = ctx->threads[ctx->current]; register cothread_state *thread = ctx->threads[ctx->current];
printf("cothread_stub() entered\n");
thread->flags |= COTHREAD_STARTED; thread->flags |= COTHREAD_STARTED;
thread->func(thread->argc,thread->argv); if (thread->func)
thread->func(thread->argc,thread->argv);
thread->flags &= ~COTHREAD_STARTED; thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0; thread->pc = 0;
// printf("uh, yeah, we shouldn't be here, but we should deal anyway\n"); //printf("uh, yeah, we shouldn't be here, but we should deal anyway\n");
} }
void cothread_switch(cothread_state *thread) { void cothread_switch(cothread_state *thread) {
@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) {
// find the number of the thread to switch to // find the number of the thread to switch to
ctx->current = thread->threadnum; ctx->current = thread->threadnum;
// fprintf(stderr,"about to switch to thread #%d\n",ctx->current); fprintf(stderr,"about to switch to thread #%d\n",ctx->current);
/* save the current stack pointer, frame pointer, and pc */ /* save the current stack pointer, frame pointer, and pc */
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp"); __asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
return; return;
enter = 1; enter = 1;
fprintf(stderr,"set stack to %p\n", thread->sp);
/* restore stack pointer and other stuff of new cothread */ /* restore stack pointer and other stuff of new cothread */
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
if (thread->flags & COTHREAD_STARTED) { if (thread->flags & COTHREAD_STARTED) {
fprintf(stderr,"in thread \n");
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
// switch to it // switch to it
longjmp(thread->jmp,1); longjmp(thread->jmp,1);
} else { } else {
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
// start it // start it
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub)); __asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
} }

View file

@ -1,17 +1,22 @@
#include <stdio.h> #include <stdio.h>
#include "glib.h"
#include "cothreads.h" #include "cothreads.h"
#include "object.h" #include "object.h"
#include "looper.h" #include "looper.h"
cothread_context *ctx;
int main(int argc,char *argv[]) { int main(int argc,char *argv[]) {
cothread_context *ctx = cothread_init();
looper *l1,*l2; looper *l1,*l2;
ctx = cothread_init();
l1 = looper_create("looperone",1,ctx); l1 = looper_create("looperone",1,ctx);
l2 = looper_create("loopertwo",0,ctx); l2 = looper_create("loopertwo",0,ctx);
object_setpeer(OBJECT(l1),OBJECT(l2)); object_setpeer(OBJECT(l1),OBJECT(l2));
fprintf(stderr,"about to start l1\n\n"); fprintf(stderr,"about to start l1\n\n");
object_start(l1); while (1)
object_start(l1);
} }