/* * Initialization. * * minithread_system_initialize: * This procedure should be called from your C main procedure * to turn a single threaded UNIX process into a multithreaded * program. * * Initialize any private data structures. * Create the idle thread. * Fork the thread which should call mainproc(mainarg) * Start scheduling. * */ void minithread_system_initialize(proc_t mainproc, arg_t mainarg) { minithread_t clean_up_thread = NULL; int a = 0; void* dummy_ptr = NULL; minithread_t tmp = NULL; tmp = NULL; dummy_ptr = (void*)&a; current_id = 0; // the next thread id to be assigned id_lock = semaphore_create(); semaphore_initialize(id_lock,1); runnable_q = multilevel_queue_new(4); blocked_q = queue_new(); blocked_q_lock = semaphore_create(); semaphore_initialize(blocked_q_lock,1); dead_q = queue_new(); dead_q_lock = semaphore_create(); semaphore_initialize(dead_q_lock,1); dead_sem = semaphore_create(); semaphore_initialize(dead_sem,0); runnable_q_lock = semaphore_create(); semaphore_initialize(runnable_q_lock,1); clean_up_thread = minithread_create(clean_up, NULL); multilevel_queue_enqueue(runnable_q, clean_up_thread->priority,clean_up_thread); runnable_count++; minithread_clock_init(TIME_QUANTA, (interrupt_handler_t)clock_handler); init_alarm(); current_thread = minithread_create(mainproc, mainarg); minithread_switch(&dummy_ptr, &(current_thread->stacktop)); return; }
/* performs any required initialization of the minimsg layer. */ void minimsg_initialize() { int i; msgmutex = semaphore_create(); semaphore_initialize(msgmutex, 1); bound_ports_free = semaphore_create(); semaphore_initialize(bound_ports_free, BOUND_MAX_PORT_NUM - BOUND_MIN_PORT_NUM + 1); // Initialize ports array ports = (miniport_t*) malloc((BOUND_MAX_PORT_NUM + 1) * sizeof(miniport_t)); if (ports == NULL) { // Fail if malloc() fails fprintf(stderr, "ERROR: minimsg_initialize() failed to malloc miniport_t array\n"); return; } // Initialize each unbound port's data elements for (i = UNBOUND_MIN_PORT_NUM; i <= UNBOUND_MAX_PORT_NUM; i++) { miniport_create_unbound(i); ports[i]->u.unbound.incoming_data = queue_new(); ports[i]->u.unbound.datagrams_ready = semaphore_create(); semaphore_initialize(ports[i]->u.unbound.datagrams_ready, 0); } }
/* Performs any initialization of the miniroute layer, if required. */ void miniroute_initialize() { network_get_my_address(hostaddr); discovery_alarm = -1; intrpt_buffer = queue_new(); intrpt_sig = semaphore_create(); discovery_mutex = semaphore_create(); discovery_sig = semaphore_create(); route_cache = miniroute_cache_new(65536, SIZE_OF_ROUTE_CACHE, MINIROUTE_CACHED_ROUTE_EXPIRE); disc_cache = miniroute_cache_new(65536, SIZE_OF_ROUTE_CACHE, MINIROUTE_CACHED_ROUTE_EXPIRE * 10); if (NULL == intrpt_buffer || NULL == intrpt_sig || NULL == route_cache || NULL == discovery_mutex || NULL == discovery_sig) { queue_free(intrpt_buffer); semaphore_destroy(intrpt_sig); semaphore_destroy(discovery_mutex); semaphore_destroy(discovery_sig); miniroute_cache_destroy(route_cache); return; } semaphore_initialize(intrpt_sig, 0); semaphore_initialize(discovery_mutex, 1); semaphore_initialize(discovery_sig, 0); network_get_my_address(hostaddr); minithread_fork(miniroute_control, NULL); }
/* Initializes the minisocket layer. */ void minisocket_initialize() { int i; sock_array = (minisocket_t*)malloc(sizeof(struct minisocket)*NUM_SOCKETS); if (!sock_array) { return; } for (i = 0; i < NUM_SOCKETS; i++) { sock_array[i] = NULL; } client_lock = semaphore_create(); if (!client_lock) { free(sock_array); return; } server_lock = semaphore_create(); if (!server_lock) { free(sock_array); semaphore_destroy(client_lock); return; } semaphore_initialize(client_lock, 1); semaphore_initialize(server_lock, 1); network_get_my_address(my_addr); curr_client_idx = CLIENT_START; //printf("minisocket_initialize complete\n"); }
/* * Creates a socket * The argument "port" is the port number of the created socket */ minisocket_t minisocket_create_socket(int port) { minisocket_t newMinisocket; newMinisocket = (minisocket_t) malloc(sizeof(struct minisocket)); if (newMinisocket == NULL) return NULL; //Initialize fields newMinisocket->port_number = port; newMinisocket->status = TCP_PORT_LISTENING; newMinisocket->seq_number = 0; newMinisocket->ack_number = 0; newMinisocket->data_buffer = NULL; newMinisocket->data_length = 0; newMinisocket->num_waiting_on_mutex = 0; newMinisocket->timeout = 100; newMinisocket->wait_for_ack_semaphore = semaphore_create(); if (newMinisocket->wait_for_ack_semaphore == NULL) { free(newMinisocket); return NULL; } semaphore_initialize(newMinisocket->wait_for_ack_semaphore, 0); newMinisocket->mutex = semaphore_create(); if (newMinisocket->mutex == NULL) { free(newMinisocket->wait_for_ack_semaphore); free(newMinisocket); return NULL; } semaphore_initialize(newMinisocket->mutex, 1); newMinisocket->packet_ready = semaphore_create(); if (newMinisocket->packet_ready == NULL) { free(newMinisocket->mutex); free(newMinisocket->wait_for_ack_semaphore); free(newMinisocket); return NULL; } semaphore_initialize(newMinisocket->packet_ready, 0); newMinisocket->waiting_packets = queue_new(); if (newMinisocket->waiting_packets == NULL) { free(newMinisocket->packet_ready); free(newMinisocket->mutex); free(newMinisocket->wait_for_ack_semaphore); free(newMinisocket); return NULL; } return newMinisocket; }
int main(int argc, char *argv[]) { sem1 = semaphore_create(); semaphore_initialize(sem1, 0); sem2 = semaphore_create(); semaphore_initialize(sem2, 0); minithread_system_initialize(thread1, NULL); return -1; }
/* This needs to: * -get a block from the in-memory blocks if possible * -otherwise pull block from disk * -increment blocks' num_open counter * -we do NOT need to save the num_open update to disk, as it is reset after a * crash anyway. * * Clients must ALWAYS check the return ID, in case a file was deleted. */ block_t _retrieve_block(int block_id) { block_t block; minifile_t inode; int ret; // todo - handle semaphores for inodes, destroy the in inode delete // First check if it's already in memory if (block_id < 0) return NULL; block = hashmap_get(retrieved_blocks, block_id); if (block != NULL && block->is_deleted == 0) { if ( block->block_type == BLOCK_TYPE_FILE || block->block_type == BLOCK_TYPE_DIRECTORY) { block->num_open++; inode = (minifile_t) block; inode->u.data.mutex = semaphore_create(); semaphore_initialize(inode->u.data.mutex, 1); } return block; } // Otherwise, get it from disk block = (block_t) malloc(sizeof(struct block)); ret = _perform_full_disk_read(disk, block_id, (char*) block); // Setup the semaphore if it's an inode type // ONly check deleted for file/dir, as data blocks can have anything if (ret == 0 && !((block->block_type == BLOCK_TYPE_FILE || block->block_type == BLOCK_TYPE_DIRECTORY) && block->is_deleted == 1)) { // Ensure num_open is set to just one, as we got it from disk (may have crashed with old data) hashmap_insert(retrieved_blocks, block_id, (void*) block); if ( block->block_type == BLOCK_TYPE_FILE || block->block_type == BLOCK_TYPE_DIRECTORY) { inode = (minifile_t) block; inode->u.data.mutex = semaphore_create(); semaphore_initialize(inode->u.data.mutex, 1); block->num_open = 1; } return block; } else { return NULL; } }
void main(void) { int maxcount = MAXCOUNT; size = head = tail = 0; empty = semaphore_create(); semaphore_initialize(empty, 0); full = semaphore_create(); semaphore_initialize(full, BUFFER_SIZE); minithread_system_initialize(producer, &maxcount); }
int main(int argc, char * argv[]) { int maxcount = MAXCOUNT; size = head = tail = 0; empty = semaphore_create(); semaphore_initialize(empty, 0); full = semaphore_create(); semaphore_initialize(full, BUFFER_SIZE); minithread_system_initialize(producer, &maxcount); return -1; }
DECLARE_TEST( semaphore, threaded ) { object_t thread[32]; int ith; int failed_waits; semaphore_test_t test; semaphore_initialize( &test.read, 0 ); semaphore_initialize( &test.write, 0 ); test.loopcount = 128; test.counter = 0; for( ith = 0; ith < 32; ++ith ) { thread[ith] = thread_create( semaphore_waiter, "semaphore_waiter", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread[ith], &test ); } test_wait_for_threads_startup( thread, 32 ); failed_waits = 0; for( ith = 0; ith < test.loopcount * 32; ++ith ) { semaphore_post( &test.read ); thread_yield(); if( !semaphore_try_wait( &test.write, 200 ) ) { failed_waits++; EXPECT_TRUE( semaphore_wait( &test.write ) ); } } for( ith = 0; ith < 32; ++ith ) { thread_terminate( thread[ith] ); thread_destroy( thread[ith] ); thread_yield(); } test_wait_for_threads_exit( thread, 32 ); EXPECT_EQ( test.counter, test.loopcount * 32 ); EXPECT_EQ( failed_waits, 0 ); semaphore_destroy( &test.read ); semaphore_destroy( &test.write ); return 0; }
/* Create a route request struct - this stores information regarding the current * route discovery attempt. */ route_request_t create_route_request() { route_request_t route_request = (route_request_t) malloc(sizeof(struct route_request)); if (route_request == NULL) return NULL; route_request->threads_waiting = 0; route_request->initiator_sem = semaphore_create(); route_request->waiting_sem = semaphore_create(); semaphore_initialize(route_request->initiator_sem, 0); semaphore_initialize(route_request->waiting_sem, 0); route_request->interrupt_arg = NULL; return route_request; }
/* Creates an unbound port for listening. Multiple requests to create the same * unbound port should return the same miniport reference. It is the responsibility * of the programmer to make sure he does not destroy unbound miniports while they * are still in use by other threads -- this would result in undefined behavior. * Unbound ports must range from 0 to 32767. If the programmer specifies a port number * outside this range, it is considered an error. */ miniport_t miniport_create_unbound(int port_number) { semaphore_P(port_mutex); if (port_number < MIN_UNBOUNDED || port_number > MAX_UNBOUNDED) { semaphore_V(port_mutex); return NULL; } if (port[port_number] != NULL) { semaphore_V(port_mutex); return port[port_number]; } if ((port[port_number] = malloc(sizeof(struct miniport))) != NULL) { port[port_number]->type = UNBOUNDED; port[port_number]->num = port_number; port[port_number]->unbound.data = queue_new(); port[port_number]->unbound.ready = semaphore_create(); if (NULL == port[port_number]->unbound.data || NULL == port[port_number]->unbound.ready) { miniport_destroy(port[port_number]); return NULL; } semaphore_initialize(port[port_number]->unbound.ready, 0); } semaphore_V(port_mutex); return port[port_number]; }
/* Creates an unbound port for listening. Multiple requests to create the same * unbound port should return the same miniport reference. It is the responsibility * of the programmer to make sure he does not destroy unbound miniports while they * are still in use by other threads -- this would result in undefined behavior. * Unbound ports must range from 0 to 32767. If the programmer specifies a port number * outside this range, it is considered an error. */ miniport_t miniport_create_unbound(int port_number) { miniport_t unbound_port; semaphore_P(msgmutex); // Ensure port_number is valid for this unbound miniport if (port_number < UNBOUND_MIN_PORT_NUM || port_number > UNBOUND_MAX_PORT_NUM) { fprintf(stderr, "ERROR: miniport_create_unbound() passed a bad port number\n"); semaphore_V(msgmutex); return NULL; } // Allocate new port IF it does not already exist if (ports[port_number] == NULL) { unbound_port = malloc(sizeof(struct miniport)); if (unbound_port == NULL) { fprintf(stderr, "ERROR: miniport_create_unbound() failed to malloc new miniport\n"); semaphore_V(msgmutex); return NULL; } unbound_port->port_type = UNBOUND; unbound_port->port_num = port_number; unbound_port->u.unbound.incoming_data = queue_new(); unbound_port->u.unbound.datagrams_ready = semaphore_create(); semaphore_initialize(unbound_port->u.unbound.datagrams_ready, 0); // Counting semaphore ports[port_number] = unbound_port; } semaphore_V(msgmutex); return ports[port_number]; }
/* * sleep with timeout in milliseconds */ void minithread_sleep_with_timeout(int delay) { // Create the sleep semaphore semaphore_t sleep_sem = semaphore_create(); interrupt_level_t prev_level; // ISO C90... // Initialize it to a value of 0 so it can act as a way to signal threads semaphore_initialize(sleep_sem, 0); // Disable interrupts prev_level = set_interrupt_level(DISABLED); // Register the alarm register_alarm(delay, &minithread_sleep_alarm_wakeup, sleep_sem); // If, at this point, interrupts were enabled, we could context switch away // the alarm could be triggered afterwards before the semaphore_P below was // called (depending on this threads priority level, etc) and then when this // thread finally calls semaphore_P(), it will hang forever. // Therefore we have interrupts disabled. // Wait on the sleep semaphore semaphore_P(sleep_sem); // Now that we've awoken, free the sleep semaphore semaphore_destroy(sleep_sem); // Restore the previous interrupt level set_interrupt_level(prev_level); // is this necessary? }
int miniterm_initialize() { pthread_t read_thread; sigset_t set; sigset_t old_set; sigfillset(&set); sigprocmask(SIG_BLOCK,&set,&old_set); kprintf("Starting read interrupts.\n"); mini_read_handler = read_handler; kb_head = NULL; kb_tail = NULL; new_data = semaphore_create(); semaphore_initialize(new_data, 0); AbortOnCondition(pthread_create(&read_thread, NULL, (void*)read_poll, NULL)!=0, "pthread"); sigdelset(&old_set,SIGRTMAX-2); sigdelset(&old_set,SIGRTMAX-1); pthread_sigmask(SIG_SETMASK,&old_set,NULL); return 0; }
DECLARE_TEST( semaphore, postwait ) { semaphore_t sem; tick_t start, end; semaphore_initialize( &sem, 0 ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_post( &sem ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_post( &sem ); semaphore_post( &sem ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); start = time_current(); semaphore_try_wait( &sem, 0 ); end = time_current(); EXPECT_LT( end - start, time_ticks_per_second() / 1000 ); start = time_current(); semaphore_try_wait( &sem, 500 ); end = time_current(); EXPECT_GE( end - start, time_ticks_per_second() / 2 ); semaphore_destroy( &sem ); return 0; }
/* Creates an unbound port for listening. Multiple requests to create the same * unbound port should return the same miniport reference. It is the responsibility * of the programmer to make sure he does not destroy unbound miniports while they * are still in use by other threads -- this would result in undefined behavior. * Unbound ports must range from 0 to 32767. If the programmer specifies a port number * outside this range, it is considered an error. */ miniport_t miniport_create_unbound(int port_number) { miniport_t new_port; if (port_number < 0 || port_number >= BOUND_PORT_START) { // user error return NULL; } if (miniport_array[port_number]) { return miniport_array[port_number]; } semaphore_P(unbound_ports_lock); new_port = (miniport_t)malloc(sizeof(struct miniport)); if (new_port == NULL) { semaphore_V(unbound_ports_lock); return NULL; } new_port->p_type = UNBOUND_PORT; new_port->p_num = port_number; new_port->u.unbound.port_pkt_q = queue_new(); if (!new_port->u.unbound.port_pkt_q) { free(new_port); semaphore_V(unbound_ports_lock); return NULL; } new_port->u.unbound.port_pkt_available_sem = semaphore_create(); if (!new_port->u.unbound.port_pkt_available_sem) { queue_free(new_port->u.unbound.port_pkt_q); free(new_port); semaphore_V(unbound_ports_lock); return NULL; } new_port->u.unbound.q_lock = semaphore_create(); if (!new_port->u.unbound.q_lock) { queue_free(new_port->u.unbound.port_pkt_q); semaphore_destroy(new_port->u.unbound.port_pkt_available_sem); free(new_port); semaphore_V(unbound_ports_lock); return NULL; } semaphore_initialize(new_port->u.unbound.port_pkt_available_sem,0); semaphore_initialize(new_port->u.unbound.q_lock,1); miniport_array[port_number] = new_port; semaphore_V(unbound_ports_lock); return new_port; }
int main() { space_sem = semaphore_create(); phone_sem = semaphore_create(); global_mutex = semaphore_create(); semaphore_initialize(space_sem, BUFFER_SIZE); semaphore_initialize(phone_sem, 0); semaphore_initialize(global_mutex, 1); current_serial_number = 0; in = out = 0; printf("Initializing system...\n"); minithread_system_initialize(initialize_threads, NULL); // Should not be reachable return -1; }
void minimsg_initialize() { g_boundPortCounter = BOUNDED_PORT_START; //bounded ports range from 32768 - 65535 memset(g_boundedPortAvail, 1, sizeof(g_boundedPortAvail)); //initialize array element to true, every port is avail when we initialize memset(g_unboundedPortPtrs, 0, sizeof(g_unboundedPortPtrs)); //set array of unbounded port pointers to null g_semaLock = semaphore_create(); AbortOnCondition(g_semaLock == NULL, "g_semaLock failed in minimsg_initialize()"); semaphore_initialize(g_semaLock, 1); //init sema to 1 (available). }
void ringbuffer_stream_initialize( stream_ringbuffer_t* stream, unsigned int buffer_size, uint64_t total_size ) { memset( stream, 0, sizeof( stream_ringbuffer_t ) ); stream_initialize( (stream_t*)stream, system_byteorder() ); stream->type = STREAMTYPE_RINGBUFFER; stream->sequential = 1; stream->path = string_format( "ringbuffer://0x%" PRIfixPTR, stream ); stream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY; ringbuffer_initialize( RINGBUFFER_FROM_STREAM( stream ), buffer_size ); semaphore_initialize( &stream->signal_read, 0 ); semaphore_initialize( &stream->signal_write, 0 ); stream->total_size = total_size; stream->vtable = &_ringbuffer_stream_vtable; }
/* performs any required initialization of the minimsg layer. */ void minimsg_initialize() { unsigned int i; network_get_my_address(my_addr); //init my_addr curr_bound_index = BOUND_PORT_START; miniport_array = (miniport_t*)malloc((MAX_PORT_NUM)*sizeof(miniport_t)); if (miniport_array == NULL) { return; } for (i = 0; i < MAX_PORT_NUM; i++) { miniport_array[i] = NULL; } bound_ports_lock = semaphore_create(); if (!bound_ports_lock){ return; } unbound_ports_lock = semaphore_create(); if (!unbound_ports_lock){ semaphore_destroy(bound_ports_lock); return; } pkt_available_sem = semaphore_create(); if (!pkt_available_sem){ semaphore_destroy(bound_ports_lock); semaphore_destroy(unbound_ports_lock); return; } pkt_q = queue_new(); if (!pkt_q){ semaphore_destroy(bound_ports_lock); semaphore_destroy(unbound_ports_lock); semaphore_destroy(pkt_available_sem); return; } semaphore_initialize(bound_ports_lock,1); semaphore_initialize(unbound_ports_lock,1); semaphore_initialize(pkt_available_sem,0); }
const char *test_semaphore1(void) { int i, j, k; atomic_count_t consumers; atomic_count_t producers; waitq_initialize(&can_start); semaphore_initialize(&sem, AT_ONCE); for (i = 1; i <= 3; i++) { thread_t *thrd; atomic_set(&items_produced, 0); atomic_set(&items_consumed, 0); consumers = i * CONSUMERS; producers = (4 - i) * PRODUCERS; TPRINTF("Creating %" PRIua " consumers and %" PRIua " producers...", consumers, producers); for (j = 0; j < (CONSUMERS + PRODUCERS) / 2; j++) { for (k = 0; k < i; k++) { thrd = thread_create(consumer, NULL, TASK, THREAD_FLAG_NONE, "consumer"); if (thrd) thread_ready(thrd); else TPRINTF("could not create consumer %d\n", i); } for (k = 0; k < (4 - i); k++) { thrd = thread_create(producer, NULL, TASK, THREAD_FLAG_NONE, "producer"); if (thrd) thread_ready(thrd); else TPRINTF("could not create producer %d\n", i); } } TPRINTF("ok\n"); thread_sleep(1); waitq_wakeup(&can_start, WAKEUP_ALL); while ((items_consumed.count != consumers) || (items_produced.count != producers)) { TPRINTF("%" PRIua " consumers remaining, %" PRIua " producers remaining\n", consumers - items_consumed.count, producers - items_produced.count); thread_sleep(1); } } return NULL; }
void minisocket_initialize() { for (int i = 0; i < N_PORTS; i++) { ports[i] = NULL; } ports_mutex = semaphore_create(); semaphore_initialize(ports_mutex, 1); n_client_ports = MIN_CLIENT_PORT; network_get_my_address(local_host); }
DECLARE_TEST( semaphore, initialize ) { semaphore_t sem; semaphore_initialize( &sem, 0 ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 1 ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 2 ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); return 0; }
/* Performs any initialization of the miniroute layer, if required. */ void miniroute_initialize() { int i; // Cache routes to hosts we've already found - it's of a static size route_cache = hashmap_create(SIZE_OF_ROUTE_CACHE, 0); // Cache the ID of the last discovery request we've seen from each host discovery_packets_seen = hashmap_create(10, 1); // The current discovery requests that are running current_discovery_requests = hashmap_create(10, 1); // The starting ID for discovery requests emanating from this host route_request_id = 0; // Setup a semaphore to control access to the route cache // also used to ensure the cache cleanup thread doesn't delete a route while // we're using it route_cache_sem = semaphore_create(); semaphore_initialize(route_cache_sem, 1); // Create a semaphore to control access to the request ID variable request_id_sem = semaphore_create(); semaphore_initialize(request_id_sem, 1); // Create a malloc'd chunk of route_req_seen structs to store info on // route requests we've recently seen route_reqs_seen = (route_req_seen_t*) malloc(sizeof(route_req_seen_t) * ROUTE_REQS_TO_STORE); for (i = 0; i < ROUTE_REQS_TO_STORE; i++) { route_reqs_seen[i] = (route_req_seen_t) malloc(sizeof(struct route_req_seen)); route_reqs_seen[i]->in_use = 0; // used to indicate this isn't in use } route_reqs_idx = 0; // Register an alarm to prune the route cache every 3 seconds register_alarm(3000, &prune_route_cache, NULL); }
/* Initializes the minisocket layer. */ void minisocket_initialize() { skt_mutex = semaphore_create(); semaphore_initialize(skt_mutex, 1); // Initialize ports array sockets = (minisocket_t*) malloc((NUM_SERVER_PORTS + NUM_CLIENT_PORTS) * sizeof(minisocket_t)); if (sockets == NULL) { // Fail if malloc() fails fprintf(stderr, "ERROR: minisocket_initialize() failed to malloc minisocket_t array\n"); return; } }
int main(int argc, char** argv) { phone_queue = queue_new(); if (phone_queue == NULL) { printf("Can't create phone queue!\n"); return 0; } /* Semaphore creation */ empty_sem = semaphore_create(); full_sem = semaphore_create(); customer_sem = semaphore_create(); semaphore_initialize(empty_sem, employee_num); semaphore_initialize(full_sem, 0); semaphore_initialize(customer_sem, 0); /* Start main thread */ minithread_system_initialize(start, NULL); return 0; }
int sink(int* arg) { channel_t* p = (channel_t *) malloc(sizeof(channel_t)); int value; p->produce = semaphore_create(); semaphore_initialize(p->produce, 0); p->consume = semaphore_create(); semaphore_initialize(p->consume, 0); minithread_fork(source, (int *) p); for (;;) { filter_t* f; semaphore_P(p->consume); value = p->value; semaphore_V(p->produce); if (value == -1) break; printf("%d is prime.\n", value); f = (filter_t *) malloc(sizeof(filter_t)); f->left = p; f->prime = value; p = (channel_t *) malloc(sizeof(channel_t)); p->produce = semaphore_create(); semaphore_initialize(p->produce, 0); p->consume = semaphore_create(); semaphore_initialize(p->consume, 0); f->right = p; minithread_fork(filter, (int *) f); } return 0; }
int main(int argc, const char* argv[]) { int segment_id; int semaphore_id; char* shared_memory; // Pick a key for the semaphore set const int semaphore_key = 6969; if (argc != 2) { printf("Usage: client segment-key\n"); exit(1); } segment_id = shmget(atoi(argv[1]), getpagesize(), 0666); if (segment_id < 0) { perror("Could not get segment"); exit(1); } semaphore_id = semaphore_allocate(key); if (semaphore_id < 0) { perror("Error allocating semaphore!"); exit(1); } if (semaphore_initialize(semaphore_id) < 0) { perror("Error intiializing semaphore!"); exit(1); } shared_memory = shmat(segment_id, NULL, 0); if (shared_memory < (char*)0) { perror("Could not attach segment"); exit(1); } semaphore_wait(semaphore_id); printf("%s\n", shared_memory); semaphore_post(semaphore_id); *shared_memory = '*'; shmdt(shared_memory); semaphore_deallocate(key); return 0; }
/* Initializes the minisocket layer. */ void minisocket_initialize() { int i = TCP_MINIMUM_SERVER; currentClientPort = 0; //int currentClientPort = 0; minisockets = (minisocket_t*) malloc(sizeof(minisocket_t) * (TCP_MAXIMUM_CLIENT - TCP_MINIMUM_SERVER + 1)); if (minisockets == NULL) return; while (i <= TCP_MAXIMUM_CLIENT) { minisockets[i] = NULL; i++; } //Mutex that controls access to the minithreads array for server ports server_mutex = semaphore_create(); semaphore_initialize(server_mutex, 1); //Mutex that controls access to the minithreads array for client ports client_mutex = semaphore_create(); semaphore_initialize(client_mutex, 1); //Queue of sockets that will be deleted sockets_to_delete = queue_new(); //Semaphore that signals the thread to delete sockets performs delete_semaphore = semaphore_create(); semaphore_initialize(delete_semaphore, 0); //Synchronize access to semaphore_destroy() destroy_semaphore = semaphore_create(); semaphore_initialize(destroy_semaphore, 1); //Fork the thread that deletes sockets on command minithread_fork((proc_t) &delete_sockets, (void*) NULL); }