mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
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:
parent
7ccc2cf90b
commit
23540ccc52
14 changed files with 531 additions and 130 deletions
|
@ -59,7 +59,7 @@ libgstinclude_HEADERS = \
|
|||
gstxml.h \
|
||||
cothreads.h
|
||||
|
||||
CFLAGS += -O2 -Wall
|
||||
CFLAGS += -g -O2 -Wall
|
||||
|
||||
libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
|
||||
libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
|
|||
cothread_state *cothread_create(cothread_context *ctx) {
|
||||
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);
|
||||
printf("new stack at %p\n",s);
|
||||
} else {
|
||||
char *sp = CURRENT_STACK_FRAME;
|
||||
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
||||
|
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
|
|||
s->ctx = ctx;
|
||||
s->threadnum = ctx->nthreads;
|
||||
s->flags = 0;
|
||||
s->sp = (int *)(s + COTHREAD_STACKSIZE);
|
||||
s->sp = ((int *)s + COTHREAD_STACKSIZE);
|
||||
|
||||
ctx->threads[ctx->nthreads++] = s;
|
||||
|
||||
// printf("created cothread at %p\n",s);
|
||||
printf("created cothread at %p %p\n",s, s->sp);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
|
|||
ctx->threads[0]->argc = 0;
|
||||
ctx->threads[0]->argv = NULL;
|
||||
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;
|
||||
|
||||
// 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
|
||||
ctx->nthreads = 1;
|
||||
|
@ -91,11 +94,13 @@ void cothread_stub() {
|
|||
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
||||
register cothread_state *thread = ctx->threads[ctx->current];
|
||||
|
||||
printf("cothread_stub() entered\n");
|
||||
thread->flags |= COTHREAD_STARTED;
|
||||
thread->func(thread->argc,thread->argv);
|
||||
if (thread->func)
|
||||
thread->func(thread->argc,thread->argv);
|
||||
thread->flags &= ~COTHREAD_STARTED;
|
||||
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) {
|
||||
|
@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) {
|
|||
|
||||
// find the number of the thread to switch to
|
||||
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 */
|
||||
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
||||
|
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
|
|||
return;
|
||||
enter = 1;
|
||||
|
||||
fprintf(stderr,"set stack to %p\n", thread->sp);
|
||||
/* restore stack pointer and other stuff of new cothread */
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
if (thread->flags & COTHREAD_STARTED) {
|
||||
fprintf(stderr,"in thread \n");
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
// switch to it
|
||||
longjmp(thread->jmp,1);
|
||||
} else {
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
// start it
|
||||
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <sys/soundcard.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//#define DEBUG_ENABLED
|
||||
|
||||
#include <gstaudiosink.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(buf != NULL);
|
||||
|
||||
|
||||
/* this has to be an audio buffer */
|
||||
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
||||
//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],
|
||||
audiosink);
|
||||
|
||||
if (GST_BUFFER_DATA(buf) != NULL) {
|
||||
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
||||
//g_print("audiosink: writing to soundcard\n");
|
||||
|
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
|
|||
if (!audiosink->mute) {
|
||||
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
||||
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(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");
|
||||
|
||||
/* 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 (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_TRIGGER) g_print("audiosink: Trigger\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);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -603,8 +603,8 @@ void gst_bin_iterate_func(GstBin *bin) {
|
|||
if (bin->need_cothreads) {
|
||||
// all we really have to do is switch to the first child
|
||||
// FIXME this should be lots more intelligent about where to start
|
||||
// g_print("** in gst_bin_iterate_func()==================================%s\n",
|
||||
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
||||
//g_print("** in gst_bin_iterate_func()==================================%s\n",
|
||||
// gst_element_get_name(GST_ELEMENT(bin->children->data)));
|
||||
cothread_switch(GST_ELEMENT(bin->children->data)->threadstate);
|
||||
} else {
|
||||
entries = bin->entries;
|
||||
|
|
1
libs/getbits/.gitignore
vendored
1
libs/getbits/.gitignore
vendored
|
@ -5,3 +5,4 @@ Makefile.in
|
|||
*.la
|
||||
.deps
|
||||
.libs
|
||||
gbtest
|
||||
|
|
|
@ -2,14 +2,19 @@ filterdir = $(libdir)/gst
|
|||
|
||||
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
|
||||
libgstgetbitsinclude_HEADERS = gstgetbits.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
|
||||
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la
|
||||
|
|
94
libs/getbits/gbtest.c
Normal file
94
libs/getbits/gbtest.c
Normal 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;
|
||||
}
|
|
@ -1,6 +1,38 @@
|
|||
#include <byteswap.h>
|
||||
#include <glib.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[] = {
|
||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
||||
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
|
||||
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;
|
||||
unsigned long result;
|
||||
|
||||
|
@ -63,9 +95,9 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
|
|||
remaining += 64;
|
||||
|
||||
/* 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 */
|
||||
dword2 = bswap_32(*(gb->ptr-4));
|
||||
dword2 = swab32(*(gb->ptr-4));
|
||||
|
||||
/* put second dword in mm4 */
|
||||
movd_m2r(dword2,mm4);
|
||||
|
@ -130,96 +162,121 @@ unsigned long getbits_mmx(gst_getbits_t *gb,unsigned long bits) {
|
|||
}
|
||||
#endif /* HAVE_LIBMMX */
|
||||
|
||||
unsigned long getbits_int(gst_getbits_t *gb,unsigned long bits) {
|
||||
int remaining;
|
||||
int result = 0;
|
||||
unsigned long _gst_getbits_int_cb(gst_getbits_t *gb, unsigned long bits) {
|
||||
int result;
|
||||
int bitsleft;
|
||||
|
||||
if (bits == 0) {
|
||||
// fprintf(stderr,"getbits(0) = 0\n");
|
||||
return 0;
|
||||
}
|
||||
//printf("gst_getbits%lu %ld %p %08x\n", bits, gb->bits, gb->ptr, gb->dword);
|
||||
|
||||
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);
|
||||
if (!bits) return 0;
|
||||
|
||||
gb->bits -= bits;
|
||||
result = gb->dword >> (32-bits);
|
||||
|
||||
if (gb->bits < 0) {
|
||||
|
||||
gb->ptr += 4;
|
||||
gb->dword = bswap_32(*((unsigned long *)(gb->ptr)));
|
||||
// gb->dword = *((unsigned char *)(gb->ptr)) << 24 |
|
||||
// *((unsigned char *)(gb->ptr)+1) << 16 |
|
||||
// *((unsigned char *)(gb->ptr)+2) << 8 |
|
||||
// *((unsigned char *)(gb->ptr)+3);
|
||||
// gb->dword = *((unsigned long *)(gb->ptr));
|
||||
gb->bits = 32;
|
||||
// fprintf(stderr,"got new dword %08x\n",gb->dword);
|
||||
/* & in the right number of bits */
|
||||
result |= (gb->dword >> (32 - remaining));
|
||||
/* shift the buffer over */
|
||||
gb->dword <<= remaining;
|
||||
/* 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);
|
||||
|
||||
bitsleft = (gb->endptr - gb->ptr)*8;
|
||||
bits = -gb->bits;
|
||||
gb->bits += (bitsleft>32? 32 : bitsleft);
|
||||
|
||||
if (gb->endptr <= gb->ptr) {
|
||||
(gb->callback)(gb, gb->data);
|
||||
gb->bits -= bits;
|
||||
}
|
||||
gb->dword = swab32(*((unsigned long *)(gb->ptr)));
|
||||
|
||||
result |= (gb->dword >> (32-bits));
|
||||
}
|
||||
// printf("have \t\t%s left\n",print_bits(gb->dword));
|
||||
// fprintf(stderr,"getbits.c:getbits(%ld) = %d\n",bits,result);
|
||||
gb->dword <<= bits;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void getbits_back_int(gst_getbits_t *gb,unsigned long bits) {
|
||||
fprintf(stderr,"getbits.c:getbits_back(%lu)\n",bits);
|
||||
// moving within the same dword...
|
||||
if ((bits + gb->bits) <= 32) {
|
||||
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 _gst_getbits_back_int(gst_getbits_t *gb, unsigned long bits) {
|
||||
gb->bits -= bits;
|
||||
gb->ptr += (gb->bits>>3);
|
||||
gb->bits &= 0x7;
|
||||
}
|
||||
|
||||
void getbits_byteback_int(gst_getbits_t *gb,unsigned long bytes) {
|
||||
fprintf(stderr,"getbits.c:getbits_byteback(%lu)\n",bytes);
|
||||
getbits_back_int(gb,bytes*8);
|
||||
gb->bits = gb->bits & ~0x07;
|
||||
unsigned long _gst_showbits_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;
|
||||
rval >>= (32-bits);
|
||||
|
||||
DEBUG("showbits%d, %08x\n", bits, rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
int getbits_offset(gst_getbits_t *gb) {
|
||||
fprintf(stderr,"getbits.c:getbits_offset() = %lu\n",gb->bits % 8);
|
||||
return gb->bits % 8;
|
||||
unsigned long _gst_getbyte(gst_getbits_t *gb, unsigned long bits) {
|
||||
return *gb->ptr++;
|
||||
}
|
||||
|
||||
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 */
|
||||
void getbits_init(gst_getbits_t *gb) {
|
||||
void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data) {
|
||||
gb->ptr = NULL;
|
||||
gb->bits = 0;
|
||||
gb->callback = callback;
|
||||
gb->data = data;
|
||||
|
||||
#ifdef HAVE_LIBMMX
|
||||
if (1) {
|
||||
|
@ -229,18 +286,30 @@ void getbits_init(gst_getbits_t *gb) {
|
|||
} else
|
||||
#endif /* HAVE_LIBMMX */
|
||||
{
|
||||
gb->getbits = getbits_int;
|
||||
gb->backbits = getbits_back_int;
|
||||
gb->backbytes = getbits_byteback_int;
|
||||
if (gb->callback) {
|
||||
gb->getbits = _gst_getbits_int_cb;
|
||||
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 */
|
||||
void getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer) {
|
||||
gb->ptr = buffer - 4;
|
||||
// fprintf(stderr,"setting ptr to %p\n",gb->ptr);
|
||||
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer, unsigned long len) {
|
||||
gb->ptr = buffer;
|
||||
gb->endptr = buffer+len;
|
||||
gb->bits = 0;
|
||||
gb->dword = 0;
|
||||
#ifdef HAVE_LIBMMX
|
||||
// gb->qword = 0;
|
||||
#endif /* HAVE_LIBMMX */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#endif /* HAVE_LIBSSE */
|
||||
|
||||
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 */
|
||||
/* 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 temp;
|
||||
|
||||
unsigned long (*getbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
|
||||
void (*backbits)(gst_getbits_t *gb,unsigned long bits); /* dword */
|
||||
void (*backbytes)(gst_getbits_t *gb,unsigned long bytes); /* dword */
|
||||
GstGetbitsCallback callback;
|
||||
void *data;
|
||||
|
||||
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
|
||||
mmx_t qword; /* qword */
|
||||
|
@ -42,18 +51,95 @@ struct _gst_getbits_t {
|
|||
};
|
||||
|
||||
|
||||
#define GST_GETBITS_INLINE
|
||||
|
||||
#ifdef GST_GETBITS_INLINE
|
||||
#include "gstgetbits_inl.h"
|
||||
#else
|
||||
|
||||
void gst_getbits_init(gst_getbits_t *gb);
|
||||
void gst_getbits_newbuf(gst_getbits_t *gb,unsigned char *buffer);
|
||||
void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data);
|
||||
void gst_getbits_newbuf(gst_getbits_t *gb, unsigned char *buffer, unsigned long len);
|
||||
|
||||
#define getbits(gb,bits) (((gb)->getbits)(gb,bits))
|
||||
#define getbits_back(gb,bits) (((gb)->backbits)(gb,bits))
|
||||
#define getbits_back_bytes(gb,bytes) (((gb)->backbytes)(gb,bytes))
|
||||
#define gst_getbits_bitoffset(gb) \
|
||||
( \
|
||||
(-(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 /* __GST_GETBITS_H__ */
|
||||
|
|
115
libs/getbits/gstgetbits_i386.s
Normal file
115
libs/getbits/gstgetbits_i386.s
Normal 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
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
/* External declarations for bitstream i/o operations. */
|
||||
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) \
|
||||
{ \
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <sys/soundcard.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//#define DEBUG_ENABLED
|
||||
|
||||
#include <gstaudiosink.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(buf != NULL);
|
||||
|
||||
|
||||
/* this has to be an audio buffer */
|
||||
// g_return_if_fail(((GstMeta *)buf->meta)->type !=
|
||||
//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],
|
||||
audiosink);
|
||||
|
||||
if (GST_BUFFER_DATA(buf) != NULL) {
|
||||
gst_trace_add_entry(NULL,0,buf,"audiosink: writing to soundcard");
|
||||
//g_print("audiosink: writing to soundcard\n");
|
||||
|
@ -219,8 +223,9 @@ void gst_audiosink_chain(GstPad *pad,GstBuffer *buf) {
|
|||
if (!audiosink->mute) {
|
||||
gst_clock_wait(audiosink->clock, GST_BUFFER_TIMESTAMP(buf), GST_OBJECT(audiosink));
|
||||
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(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");
|
||||
|
||||
/* 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 (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_TRIGGER) g_print("audiosink: Trigger\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);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
@ -15,8 +15,11 @@ pthread_key_t _cothread_key = -1;
|
|||
cothread_state *cothread_create(cothread_context *ctx) {
|
||||
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);
|
||||
printf("new stack at %p\n",s);
|
||||
} else {
|
||||
char *sp = CURRENT_STACK_FRAME;
|
||||
unsigned long *stack_end = (unsigned long *)((unsigned long)sp &
|
||||
|
@ -34,11 +37,11 @@ cothread_state *cothread_create(cothread_context *ctx) {
|
|||
s->ctx = ctx;
|
||||
s->threadnum = ctx->nthreads;
|
||||
s->flags = 0;
|
||||
s->sp = (int *)(s + COTHREAD_STACKSIZE);
|
||||
s->sp = ((int *)s + COTHREAD_STACKSIZE);
|
||||
|
||||
ctx->threads[ctx->nthreads++] = s;
|
||||
|
||||
// printf("created cothread at %p\n",s);
|
||||
printf("created cothread at %p %p\n",s, s->sp);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -56,7 +59,7 @@ cothread_context *cothread_init() {
|
|||
if (_cothread_key == -1) {
|
||||
if (pthread_key_create(&_cothread_key,NULL) != 0) {
|
||||
perror("pthread_key_create");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pthread_setspecific(_cothread_key,ctx);
|
||||
|
@ -70,10 +73,10 @@ cothread_context *cothread_init() {
|
|||
ctx->threads[0]->argc = 0;
|
||||
ctx->threads[0]->argv = NULL;
|
||||
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;
|
||||
|
||||
// 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
|
||||
ctx->nthreads = 1;
|
||||
|
@ -91,11 +94,13 @@ void cothread_stub() {
|
|||
cothread_context *ctx = pthread_getspecific(_cothread_key);
|
||||
register cothread_state *thread = ctx->threads[ctx->current];
|
||||
|
||||
printf("cothread_stub() entered\n");
|
||||
thread->flags |= COTHREAD_STARTED;
|
||||
thread->func(thread->argc,thread->argv);
|
||||
if (thread->func)
|
||||
thread->func(thread->argc,thread->argv);
|
||||
thread->flags &= ~COTHREAD_STARTED;
|
||||
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) {
|
||||
|
@ -122,7 +127,7 @@ void cothread_switch(cothread_state *thread) {
|
|||
|
||||
// find the number of the thread to switch to
|
||||
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 */
|
||||
__asm__("movl %%esp, %0" : "=m"(current->sp) : : "esp", "ebp");
|
||||
|
@ -131,12 +136,15 @@ void cothread_switch(cothread_state *thread) {
|
|||
return;
|
||||
enter = 1;
|
||||
|
||||
fprintf(stderr,"set stack to %p\n", thread->sp);
|
||||
/* restore stack pointer and other stuff of new cothread */
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
if (thread->flags & COTHREAD_STARTED) {
|
||||
fprintf(stderr,"in thread \n");
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
// switch to it
|
||||
longjmp(thread->jmp,1);
|
||||
} else {
|
||||
__asm__("movl %0, %%esp\n" : "=m"(thread->sp));
|
||||
// start it
|
||||
__asm__("jmp " SYMBOL_NAME_STR(cothread_stub));
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "glib.h"
|
||||
#include "cothreads.h"
|
||||
#include "object.h"
|
||||
#include "looper.h"
|
||||
|
||||
cothread_context *ctx;
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
cothread_context *ctx = cothread_init();
|
||||
looper *l1,*l2;
|
||||
|
||||
ctx = cothread_init();
|
||||
|
||||
l1 = looper_create("looperone",1,ctx);
|
||||
l2 = looper_create("loopertwo",0,ctx);
|
||||
object_setpeer(OBJECT(l1),OBJECT(l2));
|
||||
|
||||
fprintf(stderr,"about to start l1\n\n");
|
||||
object_start(l1);
|
||||
while (1)
|
||||
object_start(l1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue