void test_string_concat() { const char *test_type = "string", *test_content = "concat"; bool ok = 1; String s1 = sinit(); String s2 = sinit(); for (int i = 0; i < 50; i++) { sinsertc(&s1, s1.size, i); } for (int i = 0; i < 50; i++) { sinsertc(&s2, s2.size, i+50); } String s3 = sconcat(s1, s2); for (int i = 0; i < 100; i++) { if (snth(s3, i) != i) { ok = 0; break; } } if (!ok) { printf("%s test fails on %s.\n", test_type, test_content); } sdestro(&s1); sdestro(&s2); sdestro(&s3); }
static void turnoutCmd(char address, char cmd, TurnoutTable *turnout_state) { int i = 0, row = 0, col = 0; if (address >= 1 && address <= 18) { i = address - 1; row = i / 3 + 1; col = 9 * (i % 3) + 8; } else if (address >= 153 && address <= 156) { i = address - 135; row = 8; col = 9 * (address - 153) + 8; } else { assert(0); } int mask = 1 << i; char *colour; char rep; // don't repeat commands if (cmd == CURVE) { if ((*turnout_state & mask) == 0) { colour = YELLOW; rep = 'C'; *turnout_state |= mask; } else { return; } } else if (cmd == STRAIGHT) { if ((*turnout_state & mask) == 0) { return; } else { colour = GREEN; rep = 'S'; *turnout_state &= ~mask; } } else { assert(0); } struct String s; sinit(&s); sputc(&s, cmd); sputc(&s, address); sputc(&s, CLEAR_SOLENOID); tioPrint(&s); sinit(&s); sputstr(&s, CURSOR_SAVE); vtPos(&s, SWITCH_ROW + row, col); sputstr(&s, colour); sputc(&s, rep); sputstr(&s, RESET); sputstr(&s, CURSOR_RESTORE); mioPrint(&s); }
slist * get_interface_names() { struct ifaddrs *ifap = NULL; struct ifaddrs *ifp; slist *sl; sl = sinit(); if(sl == NULL) return NULL; if(getifaddrs(&ifap)) { sfree(sl); return NULL; } for(ifp = ifap; ifp; ifp = ifp->ifa_next) { if(ifp->ifa_addr == 0 || ifp->ifa_addr->sa_family != AF_INET) continue; if(sadd(sl, ifp->ifa_name) == -1) { sfree(sl); sl = NULL; break; } } freeifaddrs(ifap); return sl; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port minit24(); // mem24 pinit(); // process table sinit(); // semaphore table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. cprintf("OS Lab 161310124\n"); mpmain(); }
slist * get_interface_names() { slist *sv; pcap_if_t *devs = NULL; pcap_if_t *dev; int ret; sv = sinit(); if(sv == NULL) return NULL; ret = pcap_findalldevs(&devs, NULL); if(ret) { sfree(sv); return NULL; } for(dev = devs; dev; dev = dev->next) { if(sadd(sv, dev->name) == -1) { sfree(sv); sv = NULL; break; } } pcap_freealldevs(devs); return sv; }
void tioRead(struct String *s) { struct String cmd; sinit(&cmd); ssettag(&cmd, CMD_USER_RX); Send( g_tio_server_tid, (char *) &cmd, sizeof(struct String), (char *) s, sizeof(struct String) ); }
void tioQuit(void) { struct String cmd; sinit(&cmd); ssettag(&cmd, CMD_QUIT); Send( g_tio_server_tid, (char *) &cmd, sizeof(struct String), (char *) 0, 0 ); }
void test_string_init() { const char *test_type = "string", *test_content = "init"; bool ok = 1; String s = sinit(); ok &= !s.size; if (!ok) { printf("%s test fails on %s.\n", test_type, test_content); } sdestro(&s); }
void test_string_insert() { const char *test_type = "string", *test_content = "insert"; bool ok = 1; String s = sinit(); for (int i = 0; i < 100; i++) { sinsertc(&s, 0, i); } for (int i = 0; i < 100; i++) { if (snth(s, i)+1 != 100-i) { ok = 0; break; } } String n = sinit(); for (int i = 0; i < 10; i++) { sinsertc(&n, 0, i+'0'); } String t = cstr2str("9876543210"); sinserts(&n, &t, 5); char *tt = str2cstr(n); if (strcmp("98765987654321043210", tt) != 0) { ok = 0; } if (!ok) { printf("%s test fails on %s.\n", test_type, test_content); } free(tt); sdestro(&s); sdestro(&t); sdestro(&n); }
slist * split(char *msg, char *delim, int strict) { slist *sl; sl = sinit(); if(!sl) return NULL; if(splitf(sl, msg, delim, strict) == -1) { sfree(sl); return NULL; } return sl; }
void drawTrackLayoutGraph(char track) { char *trackA = "\033[2;44H" "-- Track A --" "\033[4;24H" "---------12--11----------------------------------\\" "\033[5;24H" "-------4/ / ---------13--------10-----------\\ \\" "\033[6;24H" " 14--/ \\ | / \\ \\" "\033[7;24H" " / \\ |/155 \\--9" "\033[8;24H" " | 156\\| |" "\033[9;24H" " | |\\154 |" "\033[10;24H" " \\ 153/| \\ /--8" "\033[11;24H" " 15--\\ / | \\ / /" "\033[12;24H" "--------\\ \\ ----------S---------S-----------/ /" "\033[13;24H" "---------1\\ \\---------6------------7------------/" "\033[14;24H" "-----------2\\ \\ /" "\033[15;24H" "-------------3-----------18--------5------------"; char *trackB = "\033[2;44H" "-- Track B --" "\033[4;24H" " ------------5--------18-----------3-------------" "\033[5;24H" " / \\ \\2-----------" "\033[6;24H" " /------------7------------6---------\\ \\1---------" "\033[7;24H" " / /-----------17--------16--------- \\ \\" "\033[8;24H" " / / \\ | / \\--15 \\-\\" "\033[9;24H" " 8--/ \\ |/153 \\ -\\" "\033[10;24H" " | 154\\| | |" "\033[11;24H" " | |\\156 | |" "\033[12;24H" " 9--\\ 155/| \\ / /-/" "\033[13;24H" " \\ \\ / | \\ /--14 /" "\033[14;24H" " \\ \\-----------10--------13--------- / /4-------" "\033[15;24H" " \\----------------------------------11--12---------"; assert(STR_MAX_LEN > strlen(trackA)); assert(STR_MAX_LEN > strlen(trackB)); String s; sinit(&s); sputstr(&s, VT_CURSOR_SAVE); vt_pos(&s, VT_TRACK_GRAPH_ROW, VT_TRACK_GRAPH_COL); sputstr(&s, VT_RESET); sputstr(&s, track == 'a' ? trackA : trackB); sputstr(&s, VT_RESET); sputstr(&s, VT_CURSOR_RESTORE); PutString(COM2, &s); }
main() { char m; vid_init(); printf("MTX starts in main()\n"); init(); // initialize and create P0 as running set_vector(80, int80h); set_vector(12, s0inth); // vector 12 for COM1 set_vector(11, s1inth); // vector 11 for COM2 sinit(); set_vector(9, kbinth); kbd_init(); lock(); set_vector(8, tinth); timer_init(); mode = LIVE; //used for demoing the time working, set to DEMO to see four procs switch by themselves kfork("/bin/u1"); // P0 kfork() P1 if(mode == DEMO) { kfork("/bin/u1"); kfork("/bin/u1"); kfork("/bin/u1"); } while(1){ //printf("P0 running\n"); while(!readyQueue); //printf("P0 switch process\n"); running->status = READY; tswitch(); // P0 switch to run P1 } }
int initialize_fio(char *envp[]) { long ps; if (endian_check()) { log_err("fio: endianness settings appear wrong.\n"); log_err("fio: please report this to [email protected]\n"); return 1; } #if !defined(CONFIG_GETTIMEOFDAY) && !defined(CONFIG_CLOCK_GETTIME) #error "No available clock source!" #endif arch_init(envp); sinit(); /* * We need locale for number printing, if it isn't set then just * go with the US format. */ if (!getenv("LC_NUMERIC")) setlocale(LC_NUMERIC, "en_US"); ps = sysconf(_SC_PAGESIZE); if (ps < 0) { log_err("Failed to get page size\n"); return 1; } page_size = ps; page_mask = ps - 1; fio_keywords_init(); return 0; }
void test_string_substr() { const char *test_type = "string", *test_content = "substr"; bool ok = 1; String s = sinit(); for (int i = 0; i < 10; i++) { sinsertc(&s, s.size, i); } String n = ssubstr(s, 3, 7); for (int i = 0; i < n.size; i++) { if (snth(n, i) != i+3) { ok = 0; break; } } if (!ok) { printf("%s test fails on %s.\n", test_type, test_content); } sdestro(&s); sdestro(&n); }
static void tioNotifier(void) { int serverTid = MyParentTid(); /* set baud: 2400 bps */ *((volatile unsigned int *) (UART1_BASE + UART_LCRM_OFFSET)) = 0x0; *((volatile unsigned int *) (UART1_BASE + UART_LCRL_OFFSET)) = 0xbf; /* disable the fifo */ volatile unsigned int *high = (volatile unsigned int *) (UART1_BASE + UART_LCRH_OFFSET); *high &= ~FEN_MASK; /* initialize the tx buffer */ g_tio_tx_buffer.head = g_tio_tx_buffer.tail = 0; g_tio_tx_buffer.buffer[0] = 0x60; g_tio_tx_buffer.buffer[1] = 0x61; g_tio_tx_buffer.buffer[2] = 0x60; g_tio_tx_buffer.buffer[3] = 0xc0; g_tio_tx_buffer.tail = 4; /* UART registers */ volatile unsigned short *data = (volatile unsigned short *) (UART1_BASE + UART_DATA_OFFSET); volatile unsigned short *flags = (volatile unsigned short *) (UART1_BASE + UART_FLAG_OFFSET); while(!(*flags & RXFE_MASK)){ (void) *data; } bool txfe = false, cts = true, clear_cts = true; while (1) { if (g_tio_quit) { break; } /* transmit data if possible */ if (txfe && clear_cts && cts && !(*flags & TXFF_MASK) && !(*flags & TXBUSY_MASK) && (*flags & CTS_MASK) && g_tio_tx_buffer.head != g_tio_tx_buffer.tail) { *data = g_tio_tx_buffer.buffer[g_tio_tx_buffer.head]; g_tio_tx_buffer.head = (g_tio_tx_buffer.head + 1) % TIO_TX_BUFFER_LEN; txfe = false; cts = false; clear_cts = false; } /* Always enable receive and modem status interrupts. * Don't need receive timeout because we aren't using FIFO. */ unsigned short int_flags = UARTEN_MASK | RIEN_MASK | MSIEN_MASK; if (!txfe) { /* Only enable transmit interrupt when we have something to send or * we're waiting to know when the transmit buffer is empty. * * Use the same software interrupt trick on transmit as mio. */ int_flags |= TIEN_MASK; } *((volatile unsigned short *) (UART1_BASE + UART_CTLR_OFFSET)) = int_flags; AwaitEvent(INT_UART1); unsigned short intr = *((volatile unsigned short *) (UART1_BASE + UART_INTR_OFFSET)); if (intr & RIS_MASK) { /* receive interrupt */ struct String str; sinit(&str); char c = *data; ssettag(&str, CMD_NOTIFIER_RX); sputc(&str, c); Send( serverTid, (char *) &str, sizeof (struct String), (char *) 0, 0 ); } if (intr & TIS_MASK) { /* transmit interrupt */ txfe = true; } if (intr & MIS_MASK) { /* modem status interrupt */ if (*flags & CTS_MASK) { cts = true; } else { clear_cts = true; } *((volatile unsigned short *) (UART1_BASE + UART_INTR_OFFSET)) = 1; } /* Software interrupt. Just clear it so we can re-evaluate the * transmit buffer state. */ *((volatile unsigned int *) (SOFTINT_BASE + VIC_SOFTWARE_INT_CLEAR)) = SOFTINT_POS; } Exit(); }
static CONN_STATE process( const POLL_MODE pollMode, const char callGrade ) { KWBoolean master = (KWBoolean) ( pollMode == POLL_ACTIVE ? KWTrue : KWFalse ); KWBoolean aborted = KWFalse; XFER_STATE state = (XFER_STATE) (master ? XFER_SENDINIT : XFER_RECVINIT); XFER_STATE old_state = XFER_EXIT; /* Initialized to any state but the original value of "state" */ XFER_STATE save_state = XFER_EXIT; char currentGrade = (char) ((unsigned char) 0xff); /*--------------------------------------------------------------------*/ /* Yea old state machine for the high level file transfer procotol */ /*--------------------------------------------------------------------*/ while( state != XFER_EXIT ) { printmsg(state == old_state ? 14 : 4 , "process: Machine state is = %c", state ); old_state = state; if ( terminate_processing != aborted ) { aborted = terminate_processing; state = XFER_ABORT; } switch( state ) { case XFER_SENDINIT: /* Initialize outgoing protocol */ state = sinit(); break; case XFER_RECVINIT: /* Initialize Receive protocol */ state = rinit(); break; case XFER_MASTER: /* Begin master mode */ master = KWTrue; state = XFER_NEXTJOB; resetGrade( ); /* Reset best grade status */ currentGrade = E_firstGrade; break; case XFER_SLAVE: /* Begin slave mode */ master = KWFalse; state = XFER_RECVHDR; break; case XFER_NEXTJOB: /* Look for work in local queue */ state = scandir( rmtname, currentGrade ); break; case XFER_REQUEST: /* Process next file in current job in queue */ state = newrequest(); break; case XFER_PUTFILE: /* Got local transmit request */ state = ssfile(); break; case XFER_GETFILE: /* Got local tranmit request */ state = srfile(); break; case XFER_SENDDATA: /* Remote accepted our work, send data */ state = sdata(); break; case XFER_SENDEOF: /* File xfer complete, send EOF */ state = seof( master ); break; case XFER_FILEDONE: /* Receive or transmit is complete */ state = (XFER_STATE) (master ? XFER_REQUEST : XFER_RECVHDR); break; case XFER_NEXTGRADE: /* Process next grade of local files */ currentGrade = nextGrade( callGrade ); if ( currentGrade ) state = XFER_NEXTJOB; else state = XFER_NOLOCAL; break; case XFER_NOLOCAL: /* No local work, remote have any? */ state = sbreak(); break; case XFER_NOREMOTE: /* No remote work, local have any? */ state = schkdir( (KWBoolean) (pollMode == POLL_ACTIVE ? KWTrue : KWFalse ), callGrade ); break; case XFER_RECVHDR: /* Receive header from other host */ state = rheader(); break; case XFER_TAKEFILE: /* Set up to receive remote requested file transfer */ state = rrfile(); break; case XFER_GIVEFILE: /* Set up to transmit remote requuest file transfer */ state = rsfile(); break; case XFER_RECVDATA: /* Receive file data from other host */ state = rdata(); break; case XFER_RECVEOF: state = reof(); break; case XFER_LOST: /* Lost the other host, flame out */ printmsg(0,"process: Connection lost to %s, " "previous system state = %c", rmtname, save_state ); hostp->status.hstatus = HS_CALL_FAILED; state = XFER_EXIT; break; case XFER_ABORT: /* Internal error, flame out */ printmsg(0,"process: Aborting connection to %s, " "previous system state = %c", rmtname, save_state ); hostp->status.hstatus = HS_CALL_FAILED; state = XFER_ENDP; break; case XFER_ENDP: /* Terminate the protocol */ state = endp(); break; default: printmsg(0,"process: Unknown state = %c, " "previous system state = %c", state, save_state ); state = XFER_ABORT; break; } /* switch */ save_state = old_state; /* Used only if we abort */ } /* while( state != XFER_EXIT ) */ /*--------------------------------------------------------------------*/ /* Protocol is complete, terminate the connection */ /*--------------------------------------------------------------------*/ return CONN_TERMINATE; } /* process */
static void mioNotifier(void) { int serverTid = MyParentTid(); /* set baud: 115.2 kbps */ *((volatile unsigned int *) (UART2_BASE + UART_LCRM_OFFSET)) = 0x0; *((volatile unsigned int *) (UART2_BASE + UART_LCRL_OFFSET)) = 0x3; /* enable the fifo */ volatile unsigned int *high = (volatile unsigned int *) (UART2_BASE + UART_LCRH_OFFSET); *high |= FEN_MASK; /* initialize the tx buffer */ g_mio_tx_buffer.head = g_mio_tx_buffer.tail = 0; while (true) { if (g_mio_quit) { break; } /* always enable receive interrupts. FIXME: what about modem status? */ unsigned short int_flags = UARTEN_MASK | RIEN_MASK | RTIEN_MASK; /* DANGER WILL ROBINSON: THIS CAN BREAK HORRIBLY! * * To prevent useless interrupts when we have nothing to send, we only * enable the transmit interrupt when necessary. However, if transmit * interrupts are disabled and we queue on some output, the output will * not be flushed until the next UART interrupt (possibly the user * typing something in). * * Since buffering output till the user types something is clearly * broken, we get around this by having the server raise the UART * interrupt in software (after loading data into g_mio_tx_buffer). This * will eventually bring us to the top of our loop, where we'll * re-evaluate our state and enable the transmit interrupt. */ if (g_mio_tx_buffer.head != g_mio_tx_buffer.tail) { /* only enable transmit interrupt if we have stuff to send */ int_flags |= TIEN_MASK; } *((volatile unsigned short *) (UART2_BASE + UART_CTLR_OFFSET)) = int_flags; /* Wait for something to happen */ AwaitEvent(INT_UART2); unsigned short intr = *((volatile unsigned short *) (UART2_BASE + UART_INTR_OFFSET)); volatile unsigned short *data = (volatile unsigned short *) (UART2_BASE + UART_DATA_OFFSET); volatile unsigned short *flags = (volatile unsigned short *) (UART2_BASE + UART_FLAG_OFFSET); if (intr & (RIS_MASK | RTIS_MASK)) { /* receive interrupt */ struct String str; sinit(&str); ssettag(&str, CMD_NOTIFIER_RX); while (!(*flags & RXFE_MASK)) { sputc(&str, *data); } Send( serverTid, (char *) &str, sizeof (struct String), (char *) 0, 0 ); } /* FIXME: we don't care about CTS for monitor? */ if (intr & TIS_MASK) { /* transmit interrupt */ while (g_mio_tx_buffer.head != g_mio_tx_buffer.tail && !(*flags & TXFF_MASK)) { *data = g_mio_tx_buffer.buffer[g_mio_tx_buffer.head]; g_mio_tx_buffer.head = (g_mio_tx_buffer.head + 1) % MIO_TX_BUFFER_LEN; } } /* Software interrupt. Just clear it so we can re-evaluate the * transmit buffer state. */ *((volatile unsigned int *) (SOFTINT_BASE + VIC_SOFTWARE_INT_CLEAR)) = SOFTINT_POS; } Exit(); }
static void tioServer(void) { Create(TIO_NOTIFIER_PRIORITY, tioNotifier); int rx_tid = -1; struct String rx_buffer; sinit(&rx_buffer); while (true) { int tid; struct String req; sinit(&req); if (g_tio_quit) { break; } Receive(&tid, (char *) &req, sizeof(struct String)); switch (stag(&req)) { default: assert(0); case CMD_NOTIFIER_RX: sconcat(&rx_buffer, &req); Reply(tid, (char *) 0, 0); break; case CMD_USER_TX: { char *buf = sbuffer(&req); for (unsigned int i = 0; i < slen(&req); ++i) { g_tio_tx_buffer.buffer[g_tio_tx_buffer.tail] = buf[i]; g_tio_tx_buffer.tail = (g_tio_tx_buffer.tail + 1) % TIO_TX_BUFFER_LEN; } Reply(tid, (char *) 0, 0); /* raise a software interrupt to inform the notifier */ *((volatile unsigned int *) (SOFTINT_BASE + VIC_SOFTWARE_INT)) = SOFTINT_POS; break; } case CMD_USER_RX: assert(rx_tid == -1); rx_tid = tid; break; case CMD_QUIT: g_tio_quit = true; Reply(tid, (char *) 0, 0); /* raise a software interrupt to quit the notifier */ *((volatile unsigned int *) (SOFTINT_BASE + VIC_SOFTWARE_INT)) = SOFTINT_POS; break; } if (slen(&rx_buffer) > 0 && rx_tid >= 0) { Reply(rx_tid, (char *) &rx_buffer, sizeof(struct String)); sinit(&rx_buffer); rx_tid = -1; } } Exit(); }
static void turnoutServer(void) { const char *rows[] = { "+--------+--------+--------+", "| 1: # | 2: # | 3: # |", "| 4: # | 5: # | 6: # |", "| 7: # | 8: # | 9: # |", "| 10: # | 11: # | 12: # |", "| 13: # | 14: # | 15: # |", "| 16: # | 17: # | 18: # |", "+--------+--------+--------+--------+", "| 153: # | 154: # | 155: # | 156: # |", "+--------+--------+--------+--------+" }; struct String s; for (unsigned int i = 0; i < sizeof(rows) / sizeof(rows[0]); i++) { sinit(&s); sputstr(&s, CURSOR_SAVE); vtPos(&s, SWITCH_ROW + i, 1); sputstr(&s, rows[i]); sputstr(&s, CURSOR_RESTORE); mioPrint(&s); } // set to all zeros (straight) so curve commands actually get sent TurnoutTable turnout_state = 0; for (int i = 1; i <= 18; ++i) { turnoutCmd(i, CURVE, &turnout_state); } for (int i = 153; i <= 156; ++i) { turnoutCmd(i, CURVE, &turnout_state); } bool quit = false; int tid; struct TurnoutMessage request; while (!quit) { int len = Receive(&tid, (char *) &request, sizeof(struct TurnoutMessage)); assert(len == sizeof(struct TurnoutMessage)); switch (request.cmd) { case CMD_TURNOUT_STRAIGHT: turnoutCmd(request.address, STRAIGHT, &turnout_state); break; case CMD_TURNOUT_CURVE: turnoutCmd(request.address, CURVE, &turnout_state); break; case CMD_TURNOUT_QUERY: // already responded break; case CMD_TURNOUT_QUIT: quit = true; break; } Reply(tid, (char *) &turnout_state, sizeof(int)); } Exit(); }
void init() { sinit(); wpos = wbuf; wlim = wbuf + WBUF_SIZE; }