/* * init_buf() * Initialize the buffering system */ void init_buf(port_t arg_ioport, int arg_coresec) { char *p; /* * Record args */ ioport = arg_ioport; coresec = arg_coresec; /* * Initialize data structures */ ll_init(&allbufs); bufpool = hash_alloc(coresec / 8); bufsize = 0; ASSERT_DEBUG(bufpool, "init_buf: bufpool"); fg_pid = gettid(); /* * Record whether DMA is supported */ p = rstat(ioport, "dma"); can_dma = p && atoi(p); /* * Spin off background thread */ bg_pid = tfork(bg_thread, 0); }
void runtime·newosproc(M *mp, void *stk) { Tfork param; Sigset oset; int32 ret; if(0) { runtime·printf( "newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n", stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp); } mp->tls[0] = mp->id; // so 386 asm can find it param.tf_tcb = (byte*)&mp->tls[0]; param.tf_tid = (int32*)&mp->procid; param.tf_stack = stk; oset = runtime·sigprocmask(SIG_SETMASK, sigset_all); ret = runtime·tfork((byte*)¶m, sizeof(param), mp, mp->g0, runtime·mstart); runtime·sigprocmask(SIG_SETMASK, oset); if(ret < 0) { runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret); if (ret == -ENOTSUP) runtime·printf("runtime: is kern.rthreads disabled?\n"); runtime·throw("runtime.newosproc"); } }
int main() { struct rwlock m; int i; int children[N_THREADS]; char *stacks[N_THREADS]; int start = uptime(); for (i = 0; i < N_THREADS; i++) stacks[i] = malloc(STACK_SIZE); rwlock(&m, OP_INIT); for (i = 0; i < N_THREADS; i++) { children[i] = tfork(child_main, &m, stacks[i] + STACK_SIZE); if (children[i] < 0) handle_error("error on tfork()"); } for (i = 0; i < N_THREADS; i++) { if (twait(children[i]) < 0) handle_error("error on twait()"); } rwlock(&m, OP_DESTROY); printf(stderr, "Program finished in %d tick(s).\n", uptime() - start); if (!time_equal(uptime() - start, ONE_SEC * N_THREADS)) handle_error("Did not finish in a correct time."); for (i = 0; i < N_THREADS; i++) free(stacks[i]); printf(stdout, "hw3-test-writelock succeeded\n"); exit(); }
int __CBeginThread( thread_fn *start_addr, void *stack_bottom, unsigned stack_size, void *arglist ) /******************************************************/ { pid_t pid; thread_args td; int rc; if( stack_bottom == NULL ) { if( stack_size == 0 ) { stack_size = 1024*4; } stack_bottom = lib_calloc( stack_size, 1 ); if( stack_bottom == NULL ) { _RWD_errno = ENOMEM; return( -1 ); } } __InitMultipleThread(); td.rtn = start_addr; td.argument = arglist; td.stack_bottom = stack_bottom; rc = __posix_sem_init( &td.event, 1, 0 ); if( rc == -1 ) return( -1 ); pid = tfork( stack_bottom, stack_size, begin_thread_helper, &td, 0 ); if( pid != -1 ) { /* suspend parent thread so that it can't call _beginthread() again before new thread extracts data from "td" (no problem if new thread calls _beginthread() since it has its own stack) */ __posix_sem_wait( &td.event ); } __posix_sem_destroy( &td.event ); return( pid ); }
static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) { int channels_mode, prediv; void *buffer; SDL_MintAudio_quit_thread = SDL_FALSE; SDL_MintAudio_thread_finished = SDL_TRUE; SDL_MintAudio_WaitThread(); Buffoper(0); Settracks(0,0); Setmontracks(0); channels_mode=STEREO16; switch (spec->format & 0xff) { case 8: if (spec->channels==2) { channels_mode=STEREO8; } else { channels_mode=MONO8; } break; } if (Setmode(channels_mode)<0) { DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); } prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; if (MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits != -1) { Gpio(GPIO_SET,7); Gpio(GPIO_WRITE, MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits); Devconnect2(DMAPLAY, DAC|EXTOUT, CLKEXT, prediv); } else { Devconnect2(DMAPLAY, DAC, CLK25M, prediv); } buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; if (Setbuffer(0, buffer, buffer + spec->size)<0) { DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); } if (SDL_MintAudio_mint_present) { SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); } else { Jdisint(MFP_DMASOUND); Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); Jenabint(MFP_DMASOUND); if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); } } Buffoper(SB_PLA_ENA|SB_PLA_RPT); DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); }
static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) { int channels_mode, dmaclock, prediv; void *buffer; /* Stop currently playing sound */ SDL_MintAudio_quit_thread = SDL_FALSE; SDL_MintAudio_thread_finished = SDL_TRUE; SDL_MintAudio_WaitThread(); Buffoper(0); /* Set replay tracks */ Settracks(0,0); Setmontracks(0); /* Select replay format */ channels_mode=STEREO16; switch (spec->format & 0xff) { case 8: if (spec->channels==2) { channels_mode=STEREO8; } else { channels_mode=MONO8; } break; } if (Setmode(channels_mode)<0) { DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); } dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock; prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; if (MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits != -1) { Gpio(GPIO_SET,7); /* DSP port gpio outputs */ Gpio(GPIO_WRITE, MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits); Devconnect2(DMAPLAY, DAC|EXTOUT, CLKEXT, prediv); } else { Devconnect2(DMAPLAY, DAC, CLK25M, prediv); } /* Set buffer */ buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; if (Setbuffer(0, buffer, buffer + spec->size)<0) { DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); } if (SDL_MintAudio_mint_present) { SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); } else { /* Install interrupt */ Jdisint(MFP_DMASOUND); /*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);*/ Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); Jenabint(MFP_DMASOUND); if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); } } /* Go */ Buffoper(SB_PLA_ENA|SB_PLA_RPT); DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); }
/* * rename() * Request rename of object within a server */ int rename(const char *src, const char *dest) { int err, tries = 0; char *p; port_name srcname, destname; /* * Explode src/dest paths into needed elements */ if (getpath(src, &srcfd, &srcname, &srcent)) { return(-1); } if (getpath(dest, &destfd, &destname, &destent)) { err = -1; goto out; } /* * Can't do this across two distinct servers */ if (srcname != destname) { err = -1; __seterr(EXDEV); goto out; } /* * Launch a thread to start the request. We will do the * matching rename. */ again: if (tfork(request, 0) < 0) { return(-1); } else { __msleep(20); /* Let'em get set */ } /* * Now connect with the destination */ if (msg(destfd, FS_RENAME, 1, destent)) { /* * If it's a transient failure (usually, the server * needs to flush a reference from the page cache), * wait a bit and try, try again. */ if (!strcmp(strerror(), EAGAIN) && (tries++ < 10)) { __msleep(20); goto again; } err = -1; goto out; } /* * Success */ err = 0; out: if (srcfd != -1) { close(srcfd); } if (destfd != -1) { close(destfd); } return(err); }