/* Creates a bound port for use in sending packets. The two parameters, addr and * remote_unbound_port_number together specify the remote's listening endpoint. * This function should assign bound port numbers incrementally between the range * 32768 to 65535. Port numbers should not be reused even if they have been destroyed, * unless an overflow occurs (ie. going over the 65535 limit) in which case you should * wrap around to 32768 again, incrementally assigning port numbers that are not * currently in use. */ miniport_t miniport_create_bound(network_address_t addr, int remote_unbound_port_number) { unsigned short start; miniport_t new_port; semaphore_P(bound_ports_lock); start = curr_bound_index; while (miniport_array[curr_bound_index] != NULL){ curr_bound_index += 1; if (curr_bound_index >= MAX_PORT_NUM){ curr_bound_index = BOUND_PORT_START; } if (curr_bound_index == start){ //bound port array full semaphore_V(bound_ports_lock); return NULL; } } new_port = (miniport_t)malloc(sizeof(struct miniport)); if (new_port == NULL) { semaphore_V(bound_ports_lock); return NULL; } new_port->p_type = BOUND_PORT; new_port->p_num = curr_bound_index; new_port->u.bound.dest_num = remote_unbound_port_number; network_address_copy(addr, new_port->u.bound.dest_addr); miniport_array[curr_bound_index] = new_port; curr_bound_index += 1; //point to next slot if (curr_bound_index >= MAX_PORT_NUM){ curr_bound_index = BOUND_PORT_START; } semaphore_V(bound_ports_lock); return new_port; }
/** * Reads the MD block and writes all the filenames in the buffer. * It reads at most numfiles names. * @param fs Pointer to datastructure on device. * @param buffer A 2 dimensional array to hold filenames. * @param numfiles Maximum number of files to read (usually size of buffer). * @return The actual number of files read from MD (can be lower than numfiles.) */ int tfs_getfiles(fs_t *fs, char buffer[][20], int numfiles) { tfs_t *tfs; gbd_request_t req; uint32_t i; int r; int files = 0; tfs = (tfs_t *)fs->internal; semaphore_P(tfs->lock); req.block = TFS_DIRECTORY_BLOCK; req.buf = ADDR_KERNEL_TO_PHYS((uint32_t)tfs->buffer_md); req.sem = NULL; r = tfs->disk->read_block(tfs->disk,&req); if(r == 0) { /* An error occured during read. */ semaphore_V(tfs->lock); return VFS_ERROR; } for(i=0;i < TFS_MAX_FILES && (int)i < numfiles;i++) { if (strlen(tfs->buffer_md[i].name) > 0) { files++; stringcopy(buffer[i], tfs->buffer_md[i].name, 100); } } semaphore_V(tfs->lock); return files; }
int vfs_create(char *pathname, int size) { char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; KERNEL_ASSERT(size >= 0); if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if(vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->create(fs, filename, size); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
/* 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]; }
/** * Opens file. Implements fs.open(). Reads directory block of tfs * device and finds given file. Returns file's inode block number or * VFS_NOT_FOUND, if file not found. * * @param fs Pointer to fs data structure of the device. * @param filename Name of the file to be opened. * * @return If file found, return inode block number as fileid, otherwise * return VFS_NOT_FOUND. */ int tfs_open(fs_t *fs, char *filename) { tfs_t *tfs; gbd_request_t req; uint32_t i; int r; tfs = (tfs_t *)fs->internal; semaphore_P(tfs->lock); req.block = TFS_DIRECTORY_BLOCK; req.buf = ADDR_KERNEL_TO_PHYS((uint32_t)tfs->buffer_md); req.sem = NULL; r = tfs->disk->read_block(tfs->disk,&req); if(r == 0) { /* An error occured during read. */ semaphore_V(tfs->lock); return VFS_ERROR; } for(i=0;i < TFS_MAX_FILES;i++) { if(stringcmp(tfs->buffer_md[i].name, filename) == 0) { semaphore_V(tfs->lock); return tfs->buffer_md[i].inode; } } semaphore_V(tfs->lock); return VFS_NOT_FOUND; }
/** * Get number of free bytes on the disk. Implements fs.getfree(). * Reads allocation blocks and counts number of zeros in the bitmap. * Result is multiplied by the block size and returned. * * @param fs Pointer to the fs data structure of the device. * * @return Number of free bytes. */ int tfs_getfree(fs_t *fs) { tfs_t *tfs = (tfs_t *)fs->internal; gbd_request_t req; int allocated = 0; uint32_t i; int r; semaphore_P(tfs->lock); req.block = TFS_ALLOCATION_BLOCK; req.buf = ADDR_KERNEL_TO_PHYS((uint32_t)tfs->buffer_bat); req.sem = NULL; r = tfs->disk->read_block(tfs->disk, &req); if(r == 0) { /* An error occured. */ semaphore_V(tfs->lock); return VFS_ERROR; } for(i=0;i<tfs->totalblocks;i++) { allocated += bitmap_get(tfs->buffer_bat,i); } semaphore_V(tfs->lock); return (tfs->totalblocks - allocated)*TFS_BLOCK_SIZE; }
/** * Seek given file to given position. The position is not verified * to be within the file's size. * * @param file Open file * * @param seek_position New positive seek position. * * @return VFS_OK, panics on invalid arguments. * */ int vfs_seek(openfile_t file, int seek_position) { openfile_entry_t *openfile; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if(seek_position < 0) { return VFS_INVALID_PARAMS; } semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } openfile->seek_position = seek_position; semaphore_V(openfile_table.sem); vfs_end_op(); return VFS_OK; }
/** * Removes given file from filesystem. * * @param pathname Full name of the file, including mountpoint. * * @return VFS_OK on success, negative (VFS_*) on failure. * */ int vfs_remove(const char *pathname) { char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_INVALID_PARAMS; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->remove(fs, filename); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
int vfs_getfree(char *filesystem) { fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(filesystem); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->getfree(fs); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
/** * Close open file. * * @param file Openfile id * * @return VFS_OK on success, negative (VFS_*) on error. * */ int vfs_close(openfile_t file) { openfile_entry_t *openfile; fs_t *fs; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; semaphore_P(openfile_table.sem); openfile = vfs_verify_open(file); if (openfile == NULL) { semaphore_V(openfile_table.sem); return VFS_NOT_OPEN; } fs = openfile->filesystem; ret = fs->close(fs, openfile->fileid); openfile->filesystem = NULL; semaphore_V(openfile_table.sem); vfs_end_op(); return ret; }
int vfs_file(char *pathname, int idx, char *buffer) { char volumename[VFS_NAME_LENGTH]; char dirname[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, dirname) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->file(fs, dirname, idx, buffer); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
/* 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]; }
// 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; }
//Destroys minisockets void minisocket_destroy(minisocket_t minisocket, int FIN) { int portNumber; int i, threads; interrupt_level_t prev_level; minisocket_error error; if (minisocket == NULL) return; portNumber = minisocket->port_number; semaphore_P(destroy_semaphore); minisocket->waiting = TCP_PORT_WAITING_TO_CLOSE; if (minisockets[portNumber] == NULL) return; semaphore_V(minisocket->packet_ready); semaphore_P(minisocket->mutex); if (minisockets[portNumber] == NULL) return; if (FIN == 1) { transmit_packet(minisocket, minisocket->destination_addr, minisocket->destination_port, 1, MSG_FIN, 0, NULL, &error); } minisocket->status = TCP_PORT_CLOSING; prev_level = set_interrupt_level(DISABLED); threads = minisocket->num_waiting_on_mutex; for (i = 0; i < threads; i++) { semaphore_V(minisocket->mutex); i++; } set_interrupt_level(prev_level); minisockets[portNumber] = NULL; semaphore_destroy(minisocket->wait_for_ack_semaphore); semaphore_destroy(minisocket->mutex); semaphore_destroy(minisocket->packet_ready); if (minisocket->data_length != 0) free(minisocket->data_buffer); queue_free(minisocket->waiting_packets); free(minisocket); semaphore_V(destroy_semaphore); }
int minithread_exit(minithread_t completed) { current_thread->status = DEAD; semaphore_P(dead_q_lock); queue_append(dead_q, current_thread); semaphore_V(dead_q_lock); semaphore_V(dead_sem); scheduler(); while(1); return 0; }
int vfs_file(char *pathname, int idx, char *buffer) { char volumename[VFS_NAME_LENGTH]; char dirname[VFS_NAME_LENGTH]; fs_t *fs = NULL; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (pathname == NULL) { semaphore_P(vfs_table.sem); for (ret = 0; ret < CONFIG_MAX_FILESYSTEMS && idx != 0; ret++) { if (vfs_table.filesystems[ret].filesystem != NULL) idx--; } /* Error can be caused if idx was <= 0 or idx was higher than the * number of mounted volumes */ if (idx != 0) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_ERROR; } stringcopy(buffer, vfs_table.filesystems[ret].mountpoint, VFS_NAME_LENGTH); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_OK; } if (vfs_parse_pathname(pathname, volumename, dirname) != VFS_OK) { vfs_end_op(); return VFS_ERROR; } semaphore_P(vfs_table.sem); fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } ret = fs->file(fs, dirname, idx, buffer); semaphore_V(vfs_table.sem); vfs_end_op(); return ret; }
/* produce all integers from 2 to max */ int source(int* arg) { channel_t* c = (channel_t *) arg; int i; for (i=2; i<=max; i++) { c->value = i; semaphore_V(c->consume); semaphore_P(c->produce); } c->value = -1; semaphore_V(c->consume); return 0; }
/** * Disk interrupt handler. Interrupt is raised so request is handled * by the disk. Sets return value of current request to zero, wakes up * function that is waiting this request and puts next request in work * by calling disk_next_request(). * * @param device Pointer to the device data structure */ static void disk_interrupt_handle(device_t *device) { disk_real_device_t *real_dev = device->real_device; disk_io_area_t *io = (disk_io_area_t *)device->io_address; spinlock_acquire(&real_dev->slock); /* Check if this interrupt was for us */ if (!(DISK_STATUS_RIRQ(io->status) || DISK_STATUS_WIRQ(io->status))) { spinlock_release(&real_dev->slock); return; } /* Just reset both flags, since the handling is identical */ io->command = DISK_COMMAND_WIRQ; io->command = DISK_COMMAND_RIRQ; /* If this assert fails, disk has caused an interrupt without any service request. */ KERNEL_ASSERT(real_dev->request_served != NULL); real_dev->request_served->return_value = 0; /* Wake up the function that is waiting this request to be handled. In case of synchronous request that is disk_submit_request. In case of asynchronous call it is some other function.*/ semaphore_V(real_dev->request_served->sem); real_dev->request_served = NULL; disk_next_request(device->generic_device); spinlock_release(&real_dev->slock); }
/* insert a task in the stack */ int InsertTask_to_Stack( task_stack_t * p_stack, robinhood_task_t * p_task ) { unsigned int prof = p_task->depth; /* don't distinguish priorities over a given depth */ if ( prof > MAX_TASK_DEPTH ) prof = MAX_TASK_DEPTH; /* take the lock on stack */ P( p_stack->stack_lock ); /* insert the task at the good depth */ p_task->next_task = p_stack->tasks_at_depth[prof]; p_stack->tasks_at_depth[prof] = p_task; /* update max_task_depth, if needed */ if ( prof > p_stack->max_task_depth ) p_stack->max_task_depth = prof; /* release the stack lock */ V( p_stack->stack_lock ); /* unblock waiting worker threads */ semaphore_V( &p_stack->sem_tasks ); return 0; }
static void update_notes(void) { int i, imax; semaphore_P(semid); imax = Panel->multi_part ? 32 : 16; for (i = 0; i < imax; i++) { if (Panel->v_flags[i]) { if (Panel->v_flags[i] == FLAG_NOTE_OFF) { Panel->ctotal[i] -= DELTA_VEL; if (Panel->ctotal[i] <= 0) { Panel->ctotal[i] = 0; Panel->v_flags[i] = 0; } } else { Panel->v_flags[i] = 0; } trace_volume(i, Panel->ctotal[i]); } if (Panel->c_flags[i]) { if (Panel->c_flags[i] & FLAG_PAN) trace_panning(i, Panel->channel[i].panning); if (Panel->c_flags[i] & FLAG_BANK) trace_bank(i, Panel->channel[i].bank); if (Panel->c_flags[i] & FLAG_PROG) trace_prog(i, Panel->channel[i].program); if (Panel->c_flags[i] & FLAG_SUST) trace_sustain(i, Panel->channel[i].sustain); Panel->c_flags[i] = 0; } } semaphore_V(semid); }
int main() { char *shm; int shmid; int producer, consumer, i; consumer=open_semaphore_set(ftok("consumer",0),1); init_a_semaphore(consumer,0,1); producer=open_semaphore_set(ftok("producer",0),1); init_a_semaphore(producer,0,1); // shm=(struct exchange *)shminit(ftok("shared",0)); if((shmid=shmget(ftok("shared",0),SHMSZ, 0666|IPC_CREAT))==-1) { printf("shmget failed.\n"); exit(1); } shm=shmat(shmid,(unsigned char *)0,0); for(i=0; ; i++) { semaphore_V(consumer); semaphore_P(producer); printf("Data receiverd: %s\n",shm); sleep(1); if(strcmp(shm,"end")==0) break; } semctl(producer,0,IPC_RMID,0); semctl(consumer,0,IPC_RMID,0); }
void minimsg_network_handler(network_interrupt_arg_t* arg) { interrupt_level_t old_level = set_interrupt_level(DISABLED); //disable interrupt //Get header and destination port mini_header_t receivedHeader; memcpy(&receivedHeader, arg->buffer, sizeof(mini_header_t)); int destPort = (int)unpack_unsigned_short(receivedHeader.destination_port); assert(destPort >= UNBOUNDED_PORT_START && destPort <= UNBOUNDED_PORT_END); // sanity checking //if the unbounded port has not been initialized, throw away the packet if (g_unboundedPortPtrs[destPort] == NULL) { set_interrupt_level(old_level); //restore interrupt level return; } //queue the packet and V the semaphore assert(g_unboundedPortPtrs[destPort]->port_type == 'u' && g_unboundedPortPtrs[destPort]->unbound_port.datagrams_ready != NULL && g_unboundedPortPtrs[destPort]->unbound_port.incoming_data != NULL); int appendSuccess = queue_append(g_unboundedPortPtrs[destPort]->unbound_port.incoming_data, (void*)arg); AbortOnCondition(appendSuccess == -1, "Queue_append failed in minimsg_network_handler()"); semaphore_V(g_unboundedPortPtrs[destPort]->unbound_port.datagrams_ready); set_interrupt_level(old_level); //restore interrupt level }
int vfs_write(openfile_t file, void *buffer, int datasize) { openfile_entry_t *openfile; fs_t *fs; int ret; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; openfile = vfs_verify_open(file); fs = openfile->filesystem; KERNEL_ASSERT(datasize >= 0 && buffer != NULL); ret = fs->write(fs, openfile->fileid, buffer, datasize, openfile->seek_position); if(ret > 0) { semaphore_P(openfile_table.sem); openfile->seek_position += ret; semaphore_V(openfile_table.sem); } vfs_end_op(); return ret; }
/* Sends a message through a locally bound port (the bound port already has an associated * receiver address so it is sufficient to just supply the bound port number). In order * for the remote system to correctly create a bound port for replies back to the sending * system, it needs to know the sender's listening port (specified by local_unbound_port). * The msg parameter is a pointer to a data payload that the user wishes to send and does not * include a network header; your implementation of minimsg_send must construct the header * before calling miniroute_send_pkt(). The return value of this function is the number of * data payload bytes sent not inclusive of the header. */ int minimsg_send(miniport_t local_unbound_port, miniport_t local_bound_port, minimsg_t msg, int len) { network_address_t dest, my_address; mini_header_t hdr; // semaphore_P(msgmutex); // Check for valid arguments if (local_unbound_port == NULL) { fprintf(stderr, "ERROR: minimsg_send() passed a NULL local_unbound_port miniport argument\n"); semaphore_V(msgmutex); return -1; } if (local_bound_port == NULL) { fprintf(stderr, "ERROR: minimsg_send() passed a NULL local_bound_port miniport argument\n"); semaphore_V(msgmutex); return -1; } // Allocate new header for packet hdr = malloc(sizeof(struct mini_header)); if (hdr == NULL) { // Could not allocate header fprintf(stderr, "ERROR: minimsg_send() failed to malloc new mini_header\n"); semaphore_V(msgmutex); return -1; } // Assemble packet header hdr->protocol = PROTOCOL_MINIDATAGRAM; // Protocol network_get_my_address(my_address); pack_address(hdr->source_address, my_address); // Source address pack_unsigned_short(hdr->source_port, local_bound_port->port_num); // Source port network_address_copy(local_bound_port->u.bound.remote_address, dest); pack_address(hdr->destination_address, dest); // Destination address pack_unsigned_short(hdr->destination_port, local_bound_port->u.bound.remote_unbound_port); // Destination port // Call miniroute_send_pkt() from network.hdr if (network_send_pkt(dest, sizeof(struct mini_header), (char*) hdr, len, msg) < 0) { // REMOVE THIS LINE // if (miniroute_send_pkt(dest, sizeof(struct mini_header), (char*) hdr, len, msg) < 0) { fprintf(stderr, "ERROR: minimsg_send() failed to successfully execute miniroute_send_pkt()\n"); semaphore_V(msgmutex); return -1; } // semaphore_V(msgmutex); 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; }
void minithread_stop() { current_thread->status = BLOCKED; semaphore_P(blocked_q_lock); queue_append(blocked_q,current_thread); semaphore_V(blocked_q_lock); scheduler(); }
//Supposed to be run in the background void delete_sockets(void *arg) { minisocket_t socket; semaphore_P(delete_semaphore); queue_dequeue(sockets_to_delete, (void**) &socket); register_alarm(15000, &delete_socket, (void*) socket); semaphore_V(delete_semaphore); }
int clean_up(){ minithread_t dead = NULL; while (1){ semaphore_P(dead_sem); semaphore_P(dead_q_lock); if (queue_dequeue(dead_q, (void**)(&dead)) == -1){ semaphore_V(dead_q_lock); return -1; } else { semaphore_V(dead_q_lock); minithread_free_stack(dead->stackbase); free(dead); } } return -1; }
/** * End a VFS operation. */ static void vfs_end_op() { semaphore_P(vfs_op_sem); vfs_ops--; KERNEL_ASSERT(vfs_ops >= 0); /* Wake up pending unmount if VFS is now idle. */ if (!vfs_usable && (vfs_ops == 0)) semaphore_V(vfs_unmount_sem); if (!vfs_usable && (vfs_ops > 0)) kprintf("VFS: %d operations still pending\n", vfs_ops); semaphore_V(vfs_op_sem); }
// An employee unpacks a phone int unpack_phone(int* arg){ while (1){ semaphore_V(phones); printf("Unpacked\n"); minithread_yield(); } }