/* _____PUBLIC FUNCTIONS_____________________________________________________ */ int main(void) { // Create a timer object tmr_t tmr; // Initialise modules led_init(); systmr_init(); // Initialise timer to expire once a second tmr_start(&tmr, TMR_TICKS_PER_SEC); for(;;) { // Wait until timer has expired while(!tmr_has_expired(&tmr)) { ; } // Reset timer tmr_reset(&tmr); // Toggle LED pin led_toggle(); } }
static int timer_event(int dev, unsigned char *event) { unsigned char cmd = event[1]; unsigned long parm = *(int *) &event[4]; switch (cmd) { case TMR_WAIT_REL: parm += prev_event_time; case TMR_WAIT_ABS: if (parm > 0) { long time; if (parm <= curr_ticks) /* It's the time */ return TIMER_NOT_ARMED; time = parm; next_event_time = prev_event_time = time; return TIMER_ARMED; } break; case TMR_START: tmr_reset(); tmr_running = 1; reprogram_timer(); break; case TMR_STOP: tmr_running = 0; break; case TMR_CONTINUE: tmr_running = 1; reprogram_timer(); break; case TMR_TEMPO: if (parm) { if (parm < 8) parm = 8; if (parm > 250) parm = 250; tmr_offs = tmr_ctr; ticks_offs += tmr2ticks(tmr_ctr); tmr_ctr = 0; curr_tempo = parm; reprogram_timer(); } break; case TMR_ECHO: seq_copy_to_input(event, 8); break; default:; } return TIMER_NOT_ARMED; }
static int timer_open(int dev, int mode) { if (opened) return -EBUSY; tmr_reset(); curr_tempo = 60; curr_timebase = 100; opened = 1; reprogram_timer(); return 0; }
static int def_tmr_open (int dev, int mode) { if (opened) return RET_ERROR (EBUSY); tmr_reset (); curr_tempo = 60; curr_timebase = HZ; opened = 1; ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1); return 0; }
static int def_tmr_open(int dev, int mode) { if (opened) return -EBUSY; tmr_reset(); curr_tempo = 60; curr_timebase = 100; opened = 1; { def_tmr.expires = (1) + jiffies; add_timer(&def_tmr); }; return 0; }
/* same as sound_timer.c:timer_ioctl!? */ static int def_tmr_ioctl(int dev, unsigned int cmd, void __user *arg) { int __user *p = arg; int val; switch (cmd) { case SNDCTL_TMR_SOURCE: return __put_user(TMR_INTERNAL, p); case SNDCTL_TMR_START: tmr_reset(); tmr_running = 1; return 0; case SNDCTL_TMR_STOP: tmr_running = 0; return 0; case SNDCTL_TMR_CONTINUE: tmr_running = 1; return 0; case SNDCTL_TMR_TIMEBASE: if (__get_user(val, p)) return -EFAULT; if (val) { if (val < 1) val = 1; if (val > 1000) val = 1000; curr_timebase = val; } return __put_user(curr_timebase, p); case SNDCTL_TMR_TEMPO: if (__get_user(val, p)) return -EFAULT; if (val) { if (val < 8) val = 8; if (val > 250) val = 250; tmr_offs = tmr_ctr; ticks_offs += tmr2ticks(tmr_ctr); tmr_ctr = 0; curr_tempo = val; reprogram_timer(); } return __put_user(curr_tempo, p); case SNDCTL_SEQ_CTRLRATE: if (__get_user(val, p)) return -EFAULT; if (val != 0) /* Can't change */ return -EINVAL; val = ((curr_tempo * curr_timebase) + 30) / 60; return __put_user(val, p); case SNDCTL_SEQ_GETTIME: return __put_user(curr_ticks, p); case SNDCTL_TMR_METRONOME: /* NOP */ break; default:; } return -EINVAL; }
static void handle_read( int cnum, struct timeval* nowP ) { char buf[30000]; /* must be larger than throttle / 2 */ int bytes_to_read, bytes_read, bytes_handled; float elapsed; ClientData client_data; register long checksum; tmr_reset( nowP, connections[cnum].idle_timer ); if ( do_throttle ) bytes_to_read = throttle / 2.0; else bytes_to_read = sizeof(buf); if ( ! connections[cnum].did_response ) { connections[cnum].did_response = 1; connections[cnum].response_at = *nowP; } #ifdef USE_SSL if ( urls[connections[cnum].url_num].protocol == PROTO_HTTPS ) bytes_read = SSL_read( connections[cnum].ssl, buf, bytes_to_read ); else bytes_read = read( connections[cnum].conn_fd, buf, bytes_to_read ); #else bytes_read = read( connections[cnum].conn_fd, buf, bytes_to_read ); #endif if ( bytes_read <= 0 ) { close_connection( cnum ); return; } for ( bytes_handled = 0; bytes_handled < bytes_read; ) { switch ( connections[cnum].conn_state ) { case CNST_HEADERS: /* State machine to read until we reach the file part. Looks for ** Content-Length header too. */ for ( ; bytes_handled < bytes_read && connections[cnum].conn_state == CNST_HEADERS; ++bytes_handled ) { switch ( connections[cnum].header_state ) { case HDST_LINE1_PROTOCOL: switch ( buf[bytes_handled] ) { case ' ': case '\t': connections[cnum].header_state = HDST_LINE1_WHITESPACE; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; } break; case HDST_LINE1_WHITESPACE: switch ( buf[bytes_handled] ) { case ' ': case '\t': break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': connections[cnum].http_status = buf[bytes_handled] - '0'; connections[cnum].header_state = HDST_LINE1_STATUS; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_LINE1_STATUS: switch ( buf[bytes_handled] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': connections[cnum].http_status = connections[cnum].http_status * 10 + buf[bytes_handled] - '0'; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_BOL: switch ( buf[bytes_handled] ) { case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; case 'C': case 'c': connections[cnum].header_state = HDST_C; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_TEXT: switch ( buf[bytes_handled] ) { case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: break; } break; case HDST_LF: switch ( buf[bytes_handled] ) { case '\n': connections[cnum].conn_state = CNST_READING; break; case '\r': connections[cnum].header_state = HDST_CR; break; case 'C': case 'c': connections[cnum].header_state = HDST_C; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CR: switch ( buf[bytes_handled] ) { case '\n': connections[cnum].header_state = HDST_CRLF; break; case '\r': connections[cnum].conn_state = CNST_READING; break; case 'C': case 'c': connections[cnum].header_state = HDST_C; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CRLF: switch ( buf[bytes_handled] ) { case '\n': connections[cnum].conn_state = CNST_READING; break; case '\r': connections[cnum].header_state = HDST_CRLFCR; break; case 'C': case 'c': connections[cnum].header_state = HDST_C; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CRLFCR: switch ( buf[bytes_handled] ) { case '\n': case '\r': connections[cnum].conn_state = CNST_READING; break; case 'C': case 'c': connections[cnum].header_state = HDST_C; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_C: switch ( buf[bytes_handled] ) { case 'O': case 'o': connections[cnum].header_state = HDST_CO; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CO: switch ( buf[bytes_handled] ) { case 'N': case 'n': connections[cnum].header_state = HDST_CON; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CON: switch ( buf[bytes_handled] ) { case 'T': case 't': connections[cnum].header_state = HDST_CONT; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONT: switch ( buf[bytes_handled] ) { case 'E': case 'e': connections[cnum].header_state = HDST_CONTE; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTE: switch ( buf[bytes_handled] ) { case 'N': case 'n': connections[cnum].header_state = HDST_CONTEN; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTEN: switch ( buf[bytes_handled] ) { case 'T': case 't': connections[cnum].header_state = HDST_CONTENT; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT: switch ( buf[bytes_handled] ) { case '-': connections[cnum].header_state = HDST_CONTENT_; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_: switch ( buf[bytes_handled] ) { case 'L': case 'l': connections[cnum].header_state = HDST_CONTENT_L; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_L: switch ( buf[bytes_handled] ) { case 'E': case 'e': connections[cnum].header_state = HDST_CONTENT_LE; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LE: switch ( buf[bytes_handled] ) { case 'N': case 'n': connections[cnum].header_state = HDST_CONTENT_LEN; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LEN: switch ( buf[bytes_handled] ) { case 'G': case 'g': connections[cnum].header_state = HDST_CONTENT_LENG; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENG: switch ( buf[bytes_handled] ) { case 'T': case 't': connections[cnum].header_state = HDST_CONTENT_LENGT; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENGT: switch ( buf[bytes_handled] ) { case 'H': case 'h': connections[cnum].header_state = HDST_CONTENT_LENGTH; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENGTH: switch ( buf[bytes_handled] ) { case ':': connections[cnum].header_state = HDST_CONTENT_LENGTH_COLON; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENGTH_COLON: switch ( buf[bytes_handled] ) { case ' ': case '\t': connections[cnum].header_state = HDST_CONTENT_LENGTH_COLON_WHITESPACE; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENGTH_COLON_WHITESPACE: switch ( buf[bytes_handled] ) { case ' ': case '\t': break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': connections[cnum].content_length = buf[bytes_handled] - '0'; connections[cnum].header_state = HDST_CONTENT_LENGTH_COLON_WHITESPACE_NUM; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; case HDST_CONTENT_LENGTH_COLON_WHITESPACE_NUM: switch ( buf[bytes_handled] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': connections[cnum].content_length = connections[cnum].content_length * 10 + buf[bytes_handled] - '0'; break; case '\n': connections[cnum].header_state = HDST_LF; break; case '\r': connections[cnum].header_state = HDST_CR; break; default: connections[cnum].header_state = HDST_TEXT; break; } break; } } break; case CNST_READING: connections[cnum].bytes += bytes_read - bytes_handled; if ( do_throttle ) { /* Check if we're reading too fast. */ elapsed = delta_timeval( &connections[cnum].started_at, nowP ) / 1000000.0; if ( elapsed > 0.01 && connections[cnum].bytes / elapsed > throttle ) { connections[cnum].conn_state = CNST_PAUSING; client_data.i = cnum; connections[cnum].wakeup_timer = tmr_create( nowP, wakeup_connection, client_data, 1000L, 0 ); } } if ( do_checksum ) { checksum = connections[cnum].checksum; for ( ; bytes_handled < bytes_read; ++bytes_handled ) { if ( checksum & 1 ) checksum = ( checksum >> 1 ) + 0x8000; else checksum >>= 1; checksum += buf[bytes_handled]; checksum &= 0xffff; } connections[cnum].checksum = checksum; } else bytes_handled = bytes_read; if ( connections[cnum].content_length != -1 && connections[cnum].bytes >= connections[cnum].content_length ) { close_connection( cnum ); return; } break; }
static int timer_ioctl (int dev, unsigned int cmd, caddr_t arg) { switch (cmd) { case SNDCTL_TMR_SOURCE: return snd_ioctl_return ((int *) arg, TMR_INTERNAL); break; case SNDCTL_TMR_START: tmr_reset (); tmr_running = 1; return 0; break; case SNDCTL_TMR_STOP: tmr_running = 0; return 0; break; case SNDCTL_TMR_CONTINUE: tmr_running = 1; return 0; break; case SNDCTL_TMR_TIMEBASE: { int val = get_fs_long ((long *) arg); if (val) { if (val < 1) val = 1; if (val > 1000) val = 1000; curr_timebase = val; } return snd_ioctl_return ((int *) arg, curr_timebase); } break; case SNDCTL_TMR_TEMPO: { int val = get_fs_long ((long *) arg); if (val) { if (val < 8) val = 8; if (val > 250) val = 250; tmr_offs = tmr_ctr; ticks_offs += tmr2ticks (tmr_ctr); tmr_ctr = 0; curr_tempo = val; reprogram_timer (); } return snd_ioctl_return ((int *) arg, curr_tempo); } break; case SNDCTL_SEQ_CTRLRATE: if (get_fs_long ((long *) arg) != 0) /* Can't change */ return -(EINVAL); return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60); break; case SNDCTL_TMR_METRONOME: /* NOP */ break; default:; } return -(EINVAL); }
static int def_tmr_ioctl (int dev, unsigned int cmd, unsigned int arg) { switch (cmd) { case SNDCTL_TMR_SOURCE: return IOCTL_OUT (arg, TMR_INTERNAL); break; case SNDCTL_TMR_START: tmr_reset (); tmr_running = 1; return 0; break; case SNDCTL_TMR_STOP: tmr_running = 0; return 0; break; case SNDCTL_TMR_CONTINUE: tmr_running = 1; return 0; break; case SNDCTL_TMR_TIMEBASE: { int val = IOCTL_IN (arg); if (val) { if (val < 1) val = 1; if (val > 1000) val = 1000; curr_timebase = val; } return IOCTL_OUT (arg, curr_timebase); } break; case SNDCTL_TMR_TEMPO: { int val = IOCTL_IN (arg); if (val) { if (val < 8) val = 8; if (val > 250) val = 250; tmr_offs = tmr_ctr; ticks_offs += tmr2ticks (tmr_ctr); tmr_ctr = 0; curr_tempo = val; } return IOCTL_OUT (arg, curr_tempo); } break; case SNDCTL_SEQ_CTRLRATE: if (IOCTL_IN (arg) != 0) /* Can't change */ return RET_ERROR (EINVAL); return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60); break; case SNDCTL_TMR_METRONOME: /* NOP */ break; default:; } return RET_ERROR (EINVAL); }
static void handle_send( connecttab* c, struct timeval* tvP ) { int sz, coast; ClientData client_data; time_t elapsed; httpd_conn* hc = c->hc; /* Do we need to write the headers first? */ if ( hc->responselen == 0 ) { /* No, just write the file. */ sz = write( hc->conn_fd, &(hc->file_address[c->bytes_sent]), MIN( c->bytes_to_send - c->bytes_sent, c->limit ) ); } else { /* Yes. We'll combine headers and file into a single writev(), ** hoping that this generates a single packet. */ struct iovec iv[2]; iv[0].iov_base = hc->response; iv[0].iov_len = hc->responselen; iv[1].iov_base = &(hc->file_address[c->bytes_sent]); iv[1].iov_len = MIN( c->bytes_to_send - c->bytes_sent, c->limit ); sz = writev( hc->conn_fd, iv, 2 ); } if ( sz == 0 || ( sz < 0 && ( errno == EWOULDBLOCK || errno == EAGAIN ) ) ) { /* This shouldn't happen, but some kernels, e.g. ** SunOS 4.1.x, are broken and select() says that ** O_NDELAY sockets are always writable even when ** they're actually not. ** ** Current workaround is to block sending on this ** socket for a brief adaptively-tuned period. ** Fortunately we already have all the necessary ** blocking code, for use with throttling. */ c->wouldblock_delay += MIN_WOULDBLOCK_DELAY; c->conn_state = CNST_PAUSING; fdwatch_del_fd( hc->conn_fd ); client_data.p = c; c->wakeup_timer = tmr_create( tvP, wakeup_connection, client_data, c->wouldblock_delay, 0 ); if ( c->wakeup_timer == (Timer*) 0 ) { syslog( LOG_CRIT, "tmr_create(wakeup_connection) failed" ); exit( 1 ); } return; } if ( sz < 0 ) { /* Something went wrong, close this connection. ** ** If it's just an EPIPE, don't bother logging, that ** just means the client hung up on us. ** ** On some systems, write() occasionally gives an EINVAL. ** Dunno why, something to do with the socket going ** bad. Anyway, we don't log those either. ** ** And ECONNRESET isn't interesting either. */ if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET ) syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl ); clear_connection( c, tvP ); return; } /* Ok, we wrote something. */ tmr_reset( tvP, c->idle_send_timer ); /* Was this a headers + file writev()? */ if ( hc->responselen > 0 ) { /* Yes; did we write only part of the headers? */ if ( sz < hc->responselen ) { /* Yes; move the unwritten part to the front of the buffer. */ int newlen = hc->responselen - sz; (void) memcpy( hc->response, &(hc->response[sz]), newlen ); hc->responselen = newlen; sz = 0; } else { /* Nope, we wrote the full headers, so adjust accordingly. */ sz -= hc->responselen; hc->responselen = 0; } } /* And update how much of the file we wrote. */ c->bytes_sent += sz; c->hc->bytes_sent += sz; /* Are we done? */ if ( c->bytes_sent >= c->bytes_to_send ) { /* This conection is finished! */ clear_connection( c, tvP ); return; } /* Tune the (blockheaded) wouldblock delay. */ if ( c->wouldblock_delay > MIN_WOULDBLOCK_DELAY ) c->wouldblock_delay -= MIN_WOULDBLOCK_DELAY; /* If we're throttling, check if we're sending too fast. */ if ( c->limit != THROTTLE_NOLIMIT ) { elapsed = tvP->tv_sec - c->started_at; if ( elapsed == 0 || c->hc->bytes_sent / elapsed > c->limit ) { c->conn_state = CNST_PAUSING; fdwatch_del_fd( hc->conn_fd ); /* When should we send the next c->limit bytes ** to get back on schedule? If less than a second ** (integer math rounding), use 1/8 second. */ coast = ( c->hc->bytes_sent + c->limit ) / c->limit - elapsed; client_data.p = c; c->wakeup_timer = tmr_create( tvP, wakeup_connection, client_data, coast ? ( coast * 1000L ) : 125L, 0 ); if ( c->wakeup_timer == (Timer*) 0 ) { syslog( LOG_CRIT, "tmr_create(wakeup_connection) failed" ); exit( 1 ); } } } }