int thread1(int* arg) { minithread_t thread = minithread_fork(thread2, NULL); printf("Thread 1.\n"); minithread_yield(); minithread_yield(); return 0; }
int receive(int* arg) { network_address_t my_address; minisocket_t socket; minisocket_error error; printf("starting receive\n"); minithread_yield(); printf("continuing receive\n"); network_get_my_address(my_address); /* create a network connection to the local machine */ socket = minisocket_client_create(my_address, port,&error); if (socket==NULL){ printf("ERROR: %s. Exiting. \n",GetErrorDescription(error)); return -1; } printf("client connected\n"); minisocket_close(socket); return 0; }
int transmit(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; minithread_t receiver1; minithread_t receiver2; miniport_t write_port1; miniport_t write_port2; network_address_t my_address; network_get_my_address(&my_address); port1 = miniport_create_unbound(0); port2 = miniport_create_unbound(1); write_port1 = miniport_create_bound(my_address, 0); write_port2 = miniport_create_bound(my_address, 1); receiver1 = minithread_fork(receive1, NULL); receiver2 = minithread_fork(receive2, NULL); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d to receiver 1.\n", i+1); sprintf(buffer, "Count for receiver 1 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port1, write_port1, buffer, length); minithread_yield(); printf("Sending packet %d to receiver 2.\n", i+1); sprintf(buffer, "Count for receiver 2 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port2, write_port2, buffer, length); } return 0; }
int transmit1(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; network_address_t addr; miniport_t port; miniport_t dest; AbortOnCondition(network_translate_hostname(hostname, addr) < 0, "Could not resolve hostname, exiting."); port = miniport_create_unbound(0); dest = miniport_create_bound(addr, 1); for (i=MAX_COUNT/2; i<MAX_COUNT; i++) { printf("Sending packet %d.\n", i+1); sprintf(buffer, "Count is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, dest, buffer, length); minithread_yield(); } return 0; }
int transmit1(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; minithread_t transmitter2; minithread_t receiver; miniport_t write_port; network_get_my_address(&my_address); port = miniport_create_unbound(0); write_port = miniport_create_bound(my_address, 0); transmitter2 = minithread_fork(transmit2, NULL); receiver = minithread_fork(receive, NULL); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d from sender 1.\n", i+1); sprintf(buffer, "Count from sender 1 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); minithread_yield(); } return 0; }
// The "produce" function int unpack(int *arg) { int new_serial_number; while(1) { semaphore_P(space_sem); // "unwrap" a phone by generating a new serial number // and placing it in the phone buffer semaphore_P(global_mutex); new_serial_number = current_serial_number++; phone_buffer[in++] = new_serial_number; if (in >= BUFFER_SIZE) in = 0; semaphore_V(global_mutex); semaphore_V(phone_sem); // if more phones have been unpacked than there are // customers, then the employee can stop working if (new_serial_number >= M_CUSTOMERS) { return 0; } minithread_yield(); } return 0; }
/* * Initialize the system to run the first minithread at * mainproc(mainarg). This procedure should be called from your * main program with the callback procedure and argument specified * as arguments. */ void minithread_system_initialize(proc_t mainproc, arg_t mainarg) { runnable_queue = multilevel_queue_new(MAX_LEVELS); stopped_queue = queue_new(); scheduler_thread = scheduler_thread_create(); assert(scheduler_thread); running_thread = scheduler_thread; int res = network_initialize((network_handler_t) network_handler); assert(res == 0); alarm_system_initialize(); minimsg_initialize(); minisocket_initialize(); reaper_thread = minithread_create(clean_stopped_threads, NULL); minithread_fork(mainproc, mainarg); interrupt_level_t prev_level = set_interrupt_level(ENABLED); minithread_clock_init(PERIOD * MILLISECOND, clock_handler); while (1) { if (!multilevel_queue_is_empty(runnable_queue)) { minithread_yield(); } } set_interrupt_level(prev_level); multilevel_queue_free(runnable_queue); queue_free(stopped_queue); }
int receive(int* arg) { char buffer[BUFFER_SIZE]; int i; int bytes_received; network_address_t my_address; minisocket_t socket; minisocket_error error; /* * It is crucial that this minithread_yield() works properly * (i.e. it really gives the processor to another thread) * othrevise the client starts before the server and it will * fail (there is nobody to connect to). */ minithread_yield(); network_get_my_address(my_address); int x; /* create a network connection to the local machine */ socket = minisocket_client_create(my_address, port,&error); if (socket==NULL){ printf("3ERROR: %s. Exiting. \n",GetErrorDescription(error)); return -1; } //semaphore_P(done_sending); /* receive the message */ bytes_received=0; while (bytes_received!=BUFFER_SIZE/20){ int received_bytes; if ((received_bytes=minisocket_receive(socket,buffer, 2, &error))==-1){ printf("inside, socket status = %d [%p]\n", socket->status, socket); printf("4ERROR: %s. Exiting. \n",GetErrorDescription(error)); /* close the connection */ minisocket_close(socket); return -1; } /* test the information received */ for (i=0; i<received_bytes; i++){ if (buffer[i]!=(char)( (bytes_received+i)%256 )){ printf("The %d'th byte received is wrong ('%d'-'%d'-'%d'-'%d' vs '%d'-'%d'-'%d'-'%d') [%d].\n", bytes_received+i, buffer[i-3], buffer[i-2], buffer[i-1], buffer[i], (bytes_received+i-3)%256, (bytes_received+i-2)%256, (bytes_received+i-1)%256, (bytes_received+i)%256, received_bytes); /* close the connection */ minisocket_close(socket); return -1; } } bytes_received+=received_bytes; } printf("All bytes received correctly (received %d bytes).\n", bytes_received); minisocket_close(socket); return 0; }
// An employee unpacks a phone int unpack_phone(int* arg){ while (1){ semaphore_V(phones); printf("Unpacked\n"); minithread_yield(); } }
int receive(int* arg) { char buffer[BUFFER_SIZE]; int i; int bytes_received; network_address_t my_address; minisocket_t socket; minisocket_error error; /* * It is crucial that this minithread_yield() works properly * (i.e. it really gives the processor to another thread) * othrevise the client starts before the server and it will * fail (there is nobody to connect to). */ minithread_yield(); network_get_my_address(my_address); /* create a network connection to the local machine */ printf("creating client\n"); socket = minisocket_client_create(my_address, port,&error); printf("client unblocked\n"); if (socket==NULL){ printf("ERROR: %s. Exiting. \n",GetErrorDescription(error)); return -1; } /* receive the message */ bytes_received=0; while (bytes_received!=BUFFER_SIZE){ int received_bytes; if ((received_bytes=minisocket_receive(socket,buffer, BUFFER_SIZE-bytes_received, &error))==-1){ printf("ERROR: %s. Exiting. \n",GetErrorDescription(error)); /* close the connection */ minisocket_close(socket); return -1; } printf("checking bytes\n"); /* test the information received */ for (i=0; i<received_bytes; i++){ if (buffer[i]!=(char)( (bytes_received+i)%256 )){ printf("The %d'th byte received is wrong.\n", bytes_received+i); /* close the connection */ minisocket_close(socket); return -1; } } bytes_received+=received_bytes; } printf("All bytes received correctly.\n"); minisocket_close(socket); return 0; }
int necromancer(int* arg) { int num_children = 2999; int i; printf("Necromancer %d spawning %d undead threads.\n", minithread_id(), num_children); for(i = 0; i < num_children; i++){ minithread_fork(zombie, NULL); } printf("Come, my servants!\n"); minithread_yield(); printf("Fascinating.\n"); return 0; }
int mainproc(int* arg) { // Creates 10 employee unpacking threads for(int i=0; i<10; i++){ minithread_t employee = minithread_fork(employee_unpack, NULL); } // Creates 10 customer threads. for(int i=0; i<10; i++){ minithread_t customer = minithread_fork(customer_getphone, NULL); } // Once the threads have been created this thread will be used as the idle thread. while(1){ minithread_yield(); } return 0; }
/* * This is the clock interrupt handling routine. * The clock handler increments the millisecond count, * deals with the multilevel queue rules for the current minithread, * and deregisters any current alarm. */ void clock_handler(void* arg) { interrupt_level_t old_level = set_interrupt_level(DISABLED); quanta_count++; max_quanta_reached(); increment_thread_quanta(); time_millis += clock_period/MILLISECOND; //gets next alarm(s) from priority queue (if it exists) alarm_t* triggered_alarm = alarm_next_triggered(time_millis); while (triggered_alarm != NULL) { //loops through, since multiple alarms could fire triggered_alarm->func(triggered_alarm->arg); free(triggered_alarm); triggered_alarm = alarm_next_triggered(time_millis); } set_interrupt_level(old_level); minithread_yield(); }
int transmit2(int* arg) { char buffer[BUFFER_SIZE]; int length; int i; miniport_t write_port; write_port = miniport_create_bound(my_address, 0); for (i=0; i<MAX_COUNT; i++) { printf("Sending packet %d from sender 2.\n", i+1); sprintf(buffer, "Count from sender 2 is %d.\n", i+1); length = strlen(buffer) + 1; minimsg_send(port, write_port, buffer, length); minithread_yield(); } return 0; }
int producer(int* arg) { int count = 1; int n, i; minithread_fork(consumer, arg); minithread_yield(); while (count <= *arg) { n = genintrand(BUFFER_SIZE); n = (n <= *arg - count + 1) ? n : *arg - count + 1; printf("Producer wants to put %d items into buffer ...\n", n); for (i=0; i<n; i++) { semaphore_P(full); printf("Producer is putting %d into buffer.\n", count); buffer[head] = count++; head = (head + 1) % BUFFER_SIZE; size++; semaphore_V(empty); } } return 0; }
//spin on a lock until it becomes available void semaphore_spinlock(tas_lock_t *lock) { while (atomic_test_and_set(lock)) minithread_yield(); }