Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

 
 
Thread Tools Display Modes
Prev Previous Post in Thread   Next Post in Thread Next
Old Feb 12th, 2007, 2:11 AM   #1
Serinth
Programmer
 
Serinth's Avatar
 
Join Date: Sep 2005
Posts: 50
Rep Power: 4 Serinth is on a distinguished road
token ring simulation

This is my assignment and i'm having a little trouble understanding how to set up and pass around the tokens/data. Any part of the code with /* ... */ is the stuff i can't get working. More specifically the token_node function and the bit at the end where it generates random data.
/*
 * The program simulates a Token Ring LAN by forking off a process
 * for each LAN node, that communicate via shared memory, instead
 * of network cables. To keep the implementation simple, it jiggles
 * out bytes instead of bits.
 *
 * It keeps a count of packets sent and received for each node.
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <errno.h>

/*
 * N_NODE defines how many nodes to simulate and MAX_DATA is the maximum data
 * size.
 */
#define	N_NODE		7
#define SIM_PACKETS	500

/*
 * Define any handy constants and structures.
 * Also define the functions.
 */
#define	MAX_DATA	250
#define	TOKEN_FLAG	1
#define	TO		2
#define	FROM		3
#define	LEN		4
#define	DATA		5
#define	DONE		6

struct data_pkt {
	char		token_flag;	/* 'T' for token, 'D' for data	*/
	char		to;		/* Destination node #		*/
	char		from;		/* Source node #		*/
	unsigned char	length;		/* Data length 1<->MAX_DATA	*/
	char		data[MAX_DATA];	/* Up to MAX_DATA bytes of data	*/
};

void token_node(int), send_pkt(int), send_byte(int, unsigned char);
void panic(char *);
unsigned char rcv_byte(int);

/*
 * The shared memory region includes a byte used to transfer data between
 * the nodes, a packet structure for each node with a packet to send and
 * sent/received counts for the nodes.
 */
struct node_data {
	unsigned char	data_xfer;
	struct data_pkt	to_send;
	int		sent;
	int		received;
	int		terminate;
};

struct shared_data {
	struct node_data node[N_NODE];
};

/*
 * Assign a number/name to each semaphore.
 * Semaphores are used to co-ordinate access to the data_xfer and
 * to_send shared data structures and also to indicate when data transfers
 * occur between nodes.
 * Macros with the node # as argument are used to access the sets of
 * semaphores.
 */
#define	EMPTY0		0
#define	FILLED0		(N_NODE)
#define	TO_SEND0	(FILLED0 + N_NODE)
#define	CRIT		(TO_SEND0 + N_NODE)
#define	NUM_SEM		(CRIT + 1)

#define	EMPTY(n)	(EMPTY0 + (n))
#define	FILLED(n)	(FILLED0 + (n))
#define	TO_SEND(n)	(TO_SEND0 + (n))

/*
 * The Linux semaphore ops are done using the fields of sembuf.
 * sem_num - Which semaphore of the set, as defined below
 * sem_op  - set to 1 for "signal" and -1 for "wait"
 * sem_flg - set to 0 for our purposes
 * The macros WAIT_SEM, SIGNAL_SEM and INITIALIZE_SEM are defined
 * to, hopefully, simplify the code.
 */
/*
 * POSIX Now says this can't be in sem.h, so we have to put it in
 * ourselves? (It was in sys/sem.h in RedHat 5.2)
 */
union semun {
	int val;
	struct semid_ds *buf;
	unsigned short int *array;
	struct seminfo *__buf;
};

#define	WAIT_SEM(s) do {						\
	struct sembuf sb;						\
	sb.sem_num = (s);						\
	sb.sem_op = -1;							\
	sb.sem_flg = 0;							\
	if (semop(semid, &sb, 1) < 0) {					\
		fprintf(stderr, "Wait sem failed errno=%d\n", errno);	\
		exit(4);						\
	}								\
    } while (0)

#define	SIGNAL_SEM(s) do {						\
	struct sembuf sb;						\
	sb.sem_num = (s);						\
	sb.sem_op = 1;							\
	sb.sem_flg = 0;							\
	if (semop(semid, &sb, 1) < 0) {					\
		fprintf(stderr, "Signal sem failed errno=%d\n", errno);	\
		exit(4);						\
	}								\
    } while (0)

#define INITIALIZE_SEM(s, n) do {					\
	union semun semarg;						\
	semarg.val = (n);						\
	if (semctl(semid, (s), SETVAL, semarg) < 0) {			\
		fprintf(stderr, "Initialize sem failed errno=%d\n", errno); \
		exit(4);						\
	}								\
    } while (0)

/*
 * Global data, (not shared between processes).
 */
int semid, snd_state, debugprintf = 0;
struct shared_data *shared_ptr;
extern int errno;
char *alphabits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

/*
 * This function is the body of a child process emulating a node.
 */
void
token_node(int num)
{

	/*
	 * If this is node #0, start the ball rolling by creating the
	 * token.
	 */
	/* ... */
	if(num==0){
		shared_ptr->node[num].to_send.token_flag='T';
		}
	
	/*
	 * Loop around processing data, until done.
	 */
	while (not_done) {
		/* ... */

		/*
		 * Handle the byte, based upon current state.
		 */
		/* ... */
		
			if (debugprintf)
				fprintf(stderr, "Got token flag %c\n", byte);
		/* ... */
	}
	exit(0);
}

/*
 * This function sends a data packet followed by the token, one byte each
 * time it is called.
 */
void
send_pkt(int num)
{

	/* ... */
	if(shared_ptr->node[num].to_send.token_flag=='T'){
		if(shared_ptr->node[num].to_send.length!=0){
			
		}
	}
		/*
		 * Start sending data packet
		 */
		if (debugprintf)
			fprintf(stderr, "Sending data packet\n");
	/* ... */
}

/*
 * Send a byte to the next node on the ring.
 */
void
send_byte(int num, unsigned char byte)
{

	/* ... */
}

/*
 * Receive a byte for this node.
 */
unsigned char
rcv_byte(int num)
{

	/* ... */
}

/*
 * The main program creates the shared memory region and forks off the
 * processes to emulate the token ring nodes.
 * This process generates packets at random and inserts them in
 * the to_send field of the nodes. When done it waits for each process
 * to be done receiving and then tells them to terminate and waits
 * for them to die and prints out the sent/received counts.
 */
int
main(int argc, char **argv)
{
	int shmid, child_status, num, to, i, j;

	/* Turn on debugging if "-d" argument specified */
	if (argc == 2 && !strcmp(argv[1], "-d"))
		debugprintf = 1;

	/*
	 * Seed the random number generator.
	 */
	srandom(time(0));

	/*
	 * Create the shared memory region.
	 */
	shmid = shmget(IPC_PRIVATE, sizeof (struct shared_data), 0600);
	if (shmid < 0) {
		fprintf(stderr, "Can't create shared memory region\n");
		exit(1);
	}

	/*
	 * and map the shared data region into our address space at an
	 * address selected by Linux.
	 */
	shared_ptr = (struct shared_data *)shmat(shmid, (char *)0, 0);
	if (shared_ptr == (struct shared_data *)0) {
		fprintf(stderr, "Can't map shared memory region\n");
		exit(2);
	}

	/*
	 * Now, create the semaphores, by creating the semaphore set.
	 * Under Linux, semaphore sets are stored in an area of memory
	 * handled much like a shared region. (A semaphore set is simply
	 * a bunch of semaphores allocated to-gether.)
	 */
	semid = semget(IPC_PRIVATE, NUM_SEM, 0600);
	if (semid < 0) {
		fprintf(stderr, "Can't create semaphore set\n");
		exit(3);
	}

	/*
	 * and initialize them.
	 * Semaphores are meaningless if they are not initialized.
	 */
	for (i = 0; i < N_NODE; i++) {
		INITIALIZE_SEM(EMPTY(i), 1);
		INITIALIZE_SEM(FILLED(i), 0);
		INITIALIZE_SEM(TO_SEND(i), 1);
	}
	INITIALIZE_SEM(CRIT, 1);

	/*
	 * And initialize the shared data
	 */
	for (i = 0; i < N_NODE; i++) {
		shared_ptr->node[i].to_send.length = 0;
		shared_ptr->node[i].sent = 0;
		shared_ptr->node[i].received = 0;
		shared_ptr->node[i].terminate = 0;
	}

	if (debugprintf)
		fprintf(stderr, "main after initialization\n");

	/*
	 * Fork off the children that simulate the disks.
	 */
	for (i = 0; i < N_NODE; i++)
		if (fork() == 0)
			token_node(i);

	/*
	 * Loop around generating packets at random.
	 * (the parent)
	 */
	for (i = 0; i < SIM_PACKETS; i++) {
		/*
		 * Add a packet to be sent to to_send for that node.
		 */
		if (debugprintf)
			fprintf(stderr, "Main in generate packets\n");
		num = random() % N_NODE;
		/* Only semaphore call(s) deleted ... */
		if (shared_ptr->node[num].to_send.length > 0)
			panic("to_send filled\n");
		shared_ptr->node[num].to_send.token_flag = 'D';
		do {
			to = random() % N_NODE;
		} while (to == num);
		shared_ptr->node[num].to_send.to = (char)to;
		shared_ptr->node[num].to_send.from = (char)num;
		shared_ptr->node[num].to_send.length = (random() % MAX_DATA) + 1;
		for (j = 0; j < shared_ptr->node[num].to_send.length; j++)
			shared_ptr->node[num].to_send.data[j] =
			    alphabits[random() % 26];
		/* Only semaphore call(s) deleted ... */
	}

	/*
	 * Now wait for all nodes to finish sending and then tell them
	 * to terminate.
	 */
	/* ... */
	for (i = 0; i < N_NODE; i++)
		shared_ptr->node[i].terminate = 1;
	/* ... */

	if (debugprintf)
		fprintf(stderr, "wait for children to terminate\n");
	/*
	 * Wait for the node processes to terminate.
	 */
	for (i = 0; i < N_NODE; i++)
		wait(&child_status);

	/*
	 * All done, just print out the results.
	 */
	for (i = 0; i < N_NODE; i++)
		printf("Node %d: sent=%d received=%d\n", i,
			shared_ptr->node[i].sent,
			shared_ptr->node[i].received);
	if (debugprintf)
		fprintf(stderr, "parent at destroy shared memory\n");
	/*
	 * And destroy the shared data area and semaphore set.
	 * First detach the shared memory segment via shmdt() and then
	 * destroy it with shmctl() using the IPC_RMID command.
	 * Destroy the semaphore set in a similar manner using a semctl()
	 * call with the IPC_RMID command.
	 */
	shmdt((char *)shared_ptr);
	shmctl(shmid, IPC_RMID, (struct shmid_ds *)0);
	semctl(semid, 0, IPC_RMID, (union semun)0);
}

/*
 * Panic: Just print out the message and exit.
 */
void
panic(char *str)
{

	fprintf(stderr, str);
	exit(5);
}

I understand that i should be setting up the token in the token_node bit but what additional processing should be done in that while(not_done) loop? Maybe i should be calling the token_node function more times as i'm trying to send it (near the bottom after the generating packets bit) Any thoughts?
__________________
A girl talked to me once.

http://www.latestanime.com
Serinth is offline   Reply With Quote
 

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Technohazard - New hacking simulation. ethereal Project Ideas 0 May 21st, 2006 10:39 AM
output - 842150451? programmingnoob C++ 3 Apr 23rd, 2006 9:23 PM
writing a scanner (lexical analysis) programmingnoob C++ 6 Mar 19th, 2006 5:12 PM
Pointers! Why? LOI Kratong C++ 33 Dec 18th, 2005 12:33 AM
Clock simulation Problem TaiChi56 Other Programming Languages 7 May 23rd, 2005 3:44 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 11:16 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC