Example #1
0
/* 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;
}
Example #2
0
/**
 * 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;
}
Example #3
0
File: vfs.c Project: Rotte/osm-k
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;
}
Example #4
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)
{
    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];
}
Example #5
0
File: tfs.c Project: ArvoX/osm
/**
 * 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;
}
Example #6
0
File: tfs.c Project: ArvoX/osm
/**
 * 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;
}
Example #7
0
File: vfs.c Project: mrb852/osm
/**
 * 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;
}
Example #8
0
File: vfs.c Project: mrb852/osm
/**
 * 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;
}
Example #9
0
File: vfs.c Project: Rotte/osm-k
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;
}
Example #10
0
File: vfs.c Project: mrb852/osm
/**
 * 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;
}
Example #11
0
File: vfs.c Project: Rotte/osm-k
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;
}
Example #12
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 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];
}
Example #13
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;
}
Example #14
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);
}
Example #15
0
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;
}
Example #16
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;
}
Example #17
0
/* 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;
}
Example #18
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);
}
Example #19
0
/* 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;

}
Example #20
0
File: tk_c.c Project: avm/timidity
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);
}
Example #21
0
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);
                }
Example #22
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
}
Example #23
0
File: vfs.c Project: Rotte/osm-k
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;
}
Example #24
0
/* 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;
}
Example #25
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;
   
}
Example #26
0
void
minithread_stop() { 
  current_thread->status = BLOCKED;
  semaphore_P(blocked_q_lock);
  queue_append(blocked_q,current_thread);
  semaphore_V(blocked_q_lock);
  scheduler();
}
Example #27
0
//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);
}
Example #28
0
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;
} 
Example #29
0
File: vfs.c Project: Rotte/osm-k
/**
 * 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);
}
Example #30
0
// An employee unpacks a phone
int
unpack_phone(int* arg){
  while (1){
    semaphore_V(phones);
    printf("Unpacked\n");
    minithread_yield();
  }
}