union semun { int val; struct semid_ds *buf; ushort_t *array; };without the "arg". That defines the type but doesn't create a variable; you can then use it:
For SETVAL, the fourth argument to semctl must be a thing of type semun. Thus, you have to define semun (almost as you did) and then write:
union semun x; x.val = 1; semctl(mysem, 0, SETVAL, x);On a lot of machines, it would work just fine to write "1" in place of x. Not on Turing. On a Sparc, there's a huge difference between passing an integer and a union.
I think that it does matter
because if the philosopher process reaches the critical section first then
the waiter may still access the state array while the philosopher is
updating his state. You don't want the waiter trying to read the state
array while one of the philosophers is modifying it.
If the waiter uses a mutex, this does not prevent the philosopher from
accessing
data if he is not using a mutex. Semaphores only work if everyone is using
them! That said, as long as the waiter only reads each entry in the state
table
once per print cycle, then the output should be fine as long as he uses a
mutex
to prevent the eating values from changing. The philosophers shouldn't need
to
use a mutex to change to the hungry state (although it wouldn't hurt I
guess.)
you "probably' could get away with not using mutex's to control changing
your own state from thinging to hungry, but:
#define LEFT (i-1)%philscan cause a lot of trouble. If there are 'phils' philosophers, and you want to see who sits to the left of philosopher zero, you would hope to get philosopher 'phils-1'.
When i=0, GCC (for some strange reason), evaluates -1%N to be a negative number.It's actually not gcc, it's the hardware. This option is blessed in the C/C++ standard, and is arguably the correct behavior.
X = Q * Y + RQ is the value returned by integer division, and R is the remainder returned by integer modulus. For example, 16 = 5 * 3 + 1 for 16/3 and 16%3. For negative numbers and integer division that truncates toward zero, that implies a negative modulus:
-1 = 0 * 5 + (-1) -6 = -1 * 5 + (-1)To get a positive modulus, you need integer division that truncates towards minus infinity:
-1 = -1 * 5 + 4 -6 = -2 * 5 + 4
struct Mesg { } shmid = shmget(../.....) mesgptr = (struct Mesg *) shmat(shmid, (char *) 0, 0)Through mesgptr shared memory can now be used as a structure, ie., the structure you created to be shared. I believe that you need the caste (struct) to get it to compile.
shmdt((void *) stuff);So it's warning you that ansi c++ won't convert your void* to the required char*. You can cast your stuff variable to a char* instead of a void* to get rid of the warning. I think the key thing to realize is that Solaris shared memory is getting you an array of bytes, while your program is using a structure.
int mutex; mutex = semget(key, nsems, semflag) mutex - holds the id of your semaphore structure key - i forget exactly what key is, someone else tell the class nsems - the number of semaphores you are requesting semflag - what you are trying to do with the semaphores, to create use IPC_CREAT | O644 - this creates and sets the semaphores so they can be easily destroyed - see project description. Don't forget this zero! The number O644 is in octal.
semop(semid, address, numsems)
semid - your semaphore set id, mutex from above.
address - the address of the structure that contains the operations
for each semaphore to be changed.
numsems - number of semaphores in that structure.
where the structure looks like:
// create a semaphore set with 1 semaphore mutex = semget(semkey, 1, 0644|IPC_CREAT)
// up() - V operation void up() { // structure to be sent struct sembuf s; s.sem_num = 0; s.sem_op = 1; s.sem_flg = 0; semop(mutex, &s, 1) }
#define FILE "/tmp/my-data-file" #define RANDOMCHAR 'H' int key; key = ftok(FILE,RANDOMCHAR);If ftok is given the same file and random character each time, it will return the same key (but things mess up if the file is deleted and then created again because ftok uses the inode number of the file in part of its calculation). With this, multiple processes can get use of the
shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0 )
getuid() << 8.br Creates a unique ID for every person. If you add a static int to this (and increment it for each new request) you can have all of you system resources linked to your user ID. And since everyone else is guaranteed to have a different user ID, your semaphores and shared memory won't be tampered with. The 8-bit shift is more than sufficient because each user can only grab a small number of semaphores. But just in case someone does, it might be a good idea for the second parameter to shmget, to use (IPC_CREAT | 0644) -- this can also be used as the third parameter to "semget".
packrat:~/cs110/test> make g++ -g -Wall -pedantic -c semaphore.cc -o semaphore.o semaphore.cc: In method `bool semaphore::FreeSem()': semaphore.cc:148: conversion from `int' to non-scalar type `semun' requested semaphore.cc: In method `bool semaphore::SetVal(int)': semaphore.cc:174: `semargs' undeclared (first use this function) semaphore.cc:174: (Each undeclared identifier is reported only once semaphore.cc:174: for each function it appears in.) semaphore.cc:177: confused by earlier errors, bailing out make: *** [semaphore.o] Error 1This code compiles fine on turing.
#ifdef SOLARIS union { int val; struct semid_ds *buf; ushort *array; } semctl_arg; #endif #ifdef LINUX semun semctl_arg; #endif
//get the memory bufferId = shmget (ftok (".", generate_number), arraylength * sizeof (buffer), (IPC_CREAT | 0664));
So, basically, the question comes down to: given the above information, is it okay that my empty seat count and occupied seat count don't always add up? Would you prefer a counting method that would always add to 20 (although I don't see an implementation of that that would be helpful)?
Answer Either way works. You need to document your output to indicate why the numbers are not always '20'.
Answer Yes, the input is well formed. The arguments to the program may not be.
Answer Yes, circular queues because that ensures that you maintain order of the people entering the barbershop. I assume there are many ways to maintain such order, but circular queues are the 'best' :-) Realize that once you start this sucker running, the circular queues slowly dement themselves to ordered linked lists. When we talk about free lists for disk drives, someone might point this out../....
Answer Yes, there are so many ways to do this that the above is probably the best statement of purpose. for example:
grunts 1 8 9 19 11 noncoms 2 6 10 12 14 etc: or 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 g n n g g n g n n g next8 9 19 0 11
Answer No. once a grunt, always a grunt../...
Answer
This is by design a little unclear, but what i need to be able to see
is the position of each grunt in the queue. So depending on how you
show queue position this could be done a number of ways. However you
do it, you need to be able to show via the printout where each grunt
is in the queue.
Answer
There is a barber chair.
Note: The number in parentheses is the "section number" which represents which section of the printed manual contains the page in question. When viewing manual pages on the computer, you sometimes need to use the "-s" command to specify the desired section. You can use the "whatis" command to find out what sections contain pages with a particular name. If there's only one page with the name (as should be true for all pages above except intro) then you can leave out the section number. For all of you Linux & BSD users out there, note that the System V version of man requires "-s" when you specify the section, unlike the GNU and BSD versions.
Also, if you wish to print a man page, you can use the "-t" flag. This will cause the output to go the printer as nicely formatted PostScript.
I took a look at it and noticed that there is definitely a problem with this requirement. the problem comes in the test() function, which sets the state of a philosopher to EATING. The problem is that if the philosopher is sleeping while in the HUNGRY state, then someone else calling test() will cause it to be marked EATING even though it's still doing its sleep(). So the waiter will still print out E for that philosopher, even though that philosopher thinks he is hungry. The end result is that you still have the problem of not seeing the HUNGRY state on printouts, and the printouts will show them EATING longer than they are supposed to. My first attempt to fix this was to move the "state[i]=EATING" statement out of test() and into take_forks(). But then the problem is that if test() is called on i followed by i+1, then i will be told it can eat (by upping its semaphore) but it won't be marked as EATING. So then when test(i+1) is called, it won't see that i is marked as EATING, so it will tell i+1 to eat. so you can get two adjacent philos eating with the same fork. oops. To fix this for real, I ended up having to make a new state called WILLEAT. I changed test() to check for WILLEAT instead of HUNGRY and changed take_forks so that it changes its state to WILLEAT immediately after the call to sleep(). Then, I have the waiter print "H" for both HUNGRY and WILLEAT. This works, although it's a big ugly. I can't see any other way to get correct behavior when using the algorithm handed out in class. It might be possible to get correct behavior from a different algorithm, but I expect most people will try to use the one you handed out. the problem is that HUNGRY is really just a new thinking state. in the original statement of the philosopher problem, HUNGRY means that the philo will eat as soon as he possibly can. In this new version, that's not true. Instead, he just has two different thinking states, followed by the old hungry state (now called WILLEAT). As before, the real hungry state (now WILLEAT) will not necessarily show up on the printout because it could take only a few microseconds. But this is covered up in the printout by printing the same thing for HUNGRY (thinking round 2, really) and WILLEAT."
I've just submitted my code for project 3, and ftok isn't working for me. It returns -1 regardless of how I set up the file and number inputs to it. How can I fix this? Thanks.
Works fine for me. Did you run ./sems in the same directory where semaphore.c exists? (The number returned by ftok was negative, but it wasn't -1.)
The general approach for this kind of problem is to look at the value of the global "errno". An easy way to do that is with strerror. For example:
#includeIf that doesn't make it clear, then look at the man page. The man page gives errors in terms of their abbreviations, such as ENOENT. To translate those into the English used by strerror, look in /usr/include/sys/errno.h. The comments in that file are precisely the messages generated by strerror.#include // ... id = ftok(...); if (id == -1) { cerr << "ftok failed: " << strerror(errno) << endl; }
Are we expected to determine if the arguments are valid integers? As far as I can tell, this is non-trivial, given the way atoi() and its cousins are designed. Can you give any pointers if we have to do this?
Don't bother. Seriously invalid integers are usually converted to zero. (More accurately, they're converted to their integral prefix.) Just take the result of atoi and check that for validity as if it were an integer -- i.e., if 0 is illegal, reject it, otherwise accept it as if it were 0.