[13] | 1 | #include "semaforo.h"
|
---|
| 2 |
|
---|
| 3 | /* Declare some local functions. */
|
---|
| 4 | FORWARD _PROTOTYPE(void init_server, (void) );
|
---|
| 5 | FORWARD _PROTOTYPE(void get_work, (message *m_ptr) );
|
---|
| 6 | FORWARD _PROTOTYPE(int do_up, (message *m_ptr) );
|
---|
| 7 | FORWARD _PROTOTYPE(int do_down, (message *m_ptr) );
|
---|
| 8 |
|
---|
| 9 | /* semaforo globale al server */
|
---|
| 10 | semaforo sema;
|
---|
| 11 |
|
---|
| 12 | /*===========================================================================*
|
---|
| 13 | * main *
|
---|
| 14 | *===========================================================================*/
|
---|
| 15 | PUBLIC int main(void){
|
---|
| 16 | message m;
|
---|
| 17 | int result;
|
---|
| 18 | /* Initialize the semaphore server. */
|
---|
| 19 | init_server();
|
---|
| 20 | /* Main loop of server. Get work and process it. */
|
---|
| 21 | while(TRUE) {
|
---|
| 22 | /* Block and wait until a request message arrives. */
|
---|
| 23 | get_work(&m);
|
---|
| 24 | /* Caller is now blocked. Dispatch based on message type. */
|
---|
| 25 | switch(m.m_type) {
|
---|
| 26 | case SS_UP: result = do_up(&m); break;
|
---|
| 27 | case SS_DOWN: result = do_down(&m); break;
|
---|
| 28 | default: result = EINVAL;
|
---|
| 29 | }
|
---|
| 30 | /* Send the reply, unless the caller must be blocked. */
|
---|
| 31 | if (result != EDONTREPLY) {
|
---|
| 32 | m.m_type = result;
|
---|
| 33 | send(m.m_source, &m);
|
---|
| 34 | }
|
---|
| 35 | }
|
---|
| 36 | return(OK);
|
---|
| 37 | }
|
---|
| 38 |
|
---|
| 39 | /*===========================================================================*
|
---|
| 40 | * init_server *
|
---|
| 41 | *===========================================================================*/
|
---|
| 42 | PRIVATE void init_server(void){
|
---|
| 43 | sema.s = 0;
|
---|
| 44 | sema.quanti = 0;
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 |
|
---|
| 48 | /*===========================================================================*
|
---|
| 49 | * get_work *
|
---|
| 50 | *===========================================================================*/
|
---|
| 51 | PRIVATE void get_work(message *m_ptr){
|
---|
| 52 | int status = 0;
|
---|
| 53 | status = receive(ANY, m_ptr); /* this blocks until message arrives */
|
---|
| 54 | if (OK != status)
|
---|
| 55 | panic("SS","failed to receive message!", status);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | PRIVATE int do_down(message *m_ptr){
|
---|
| 59 | if (sema.s > 0){
|
---|
| 60 | sema.s -= 1;
|
---|
| 61 | return(OK);
|
---|
| 62 | }
|
---|
| 63 | if (accoda(&sema, m_ptr->m_source) < 0) return(EFAULT);
|
---|
| 64 | printf("Accodato %d (semaforo %d [%d])\n",
|
---|
| 65 | m_ptr->m_source, sema.s, sema.quanti);
|
---|
| 66 | return(EDONTREPLY); /* non risponde: il chiamante rimane bloccato */
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | PRIVATE int do_up(message *m_ptr){
|
---|
| 70 | sema.s += 1;
|
---|
| 71 | if (sema.quanti > 0){
|
---|
| 72 | int waiting = scoda(&sema);
|
---|
| 73 | if (waiting < 0) return(EFAULT);
|
---|
| 74 | sema.s -= 1;
|
---|
| 75 | printf("Scodato %d (semaforo %d [%d])\n",
|
---|
| 76 | waiting, sema.s, sema.quanti);
|
---|
| 77 | m_ptr->m_type = OK;
|
---|
| 78 | send(waiting, m_ptr);
|
---|
| 79 | }
|
---|
| 80 | return(OK);
|
---|
| 81 | }
|
---|