summaryrefslogtreecommitdiffabout
path: root/lib/scoreboard.cc
Side-by-side diff
Diffstat (limited to 'lib/scoreboard.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/scoreboard.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/scoreboard.cc b/lib/scoreboard.cc
new file mode 100644
index 0000000..370cd93
--- a/dev/null
+++ b/lib/scoreboard.cc
@@ -0,0 +1,71 @@
+#ifdef USE_PCH
+ #include "pch.h"
+#else
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
+ #include <cassert>
+ #include <string>
+ #include <konforka/exception.h>
+ using namespace std;
+ #include "sitecing/scoreboard.h"
+#endif
+
+namespace sitecing {
+
+ scoreboard::scoreboard()
+ : shmid(-1), slots(NULL) {
+ shmid = shmget(IPC_PRIVATE,MAX_SITECING_SCOREBOARD_SLOTS*sizeof(scoreboard_slot),IPC_CREAT|0600);
+ if(shmid<0)
+ throw konforka::exception(CODEPOINT,"failed to shmget()");
+ slots = (scoreboard_slot*)shmat(shmid,NULL,0);
+ if(shmctl(shmid,IPC_RMID,NULL))
+ throw konforka::exception(CODEPOINT,"failed to shmctl()");
+ if(!slots)
+ throw konforka::exception(CODEPOINT,"failed to shmat()");
+ for(int tmp=0;tmp<MAX_SITECING_SCOREBOARD_SLOTS;tmp++)
+ slots[tmp].state=scoreboard_slot::state_free;
+ }
+ scoreboard::~scoreboard() {
+ shmdt(slots);
+ }
+
+ int scoreboard::allocate_slot() {
+ for(int tmp=0;tmp<MAX_SITECING_SCOREBOARD_SLOTS;tmp++) {
+ if(slots[tmp].state==scoreboard_slot::state_free) {
+ slots[tmp].state=scoreboard_slot::state_allocated;
+ slots[tmp].pid=0;
+ return tmp;
+ }
+ }
+ throw konforka::exception(CODEPOINT,"out of scoreboard slots");
+ }
+ void scoreboard::free_slot(int slot) {
+ assert(slot>=0 && slot<MAX_SITECING_SCOREBOARD_SLOTS);
+ if(slots[slot].state==scoreboard_slot::state_free)
+ throw konforka::exception(CODEPOINT,"freeing unallocated slot");
+ slots[slot].state=scoreboard_slot::state_free;
+ }
+
+ scoreboard_slot *scoreboard::get_slot(int slot) {
+ assert(slot>=0 && slot<MAX_SITECING_SCOREBOARD_SLOTS);
+ return &slots[slot];
+ }
+ int scoreboard::get_slot_by_pid(pid_t pid) {
+ for(int rv=0;rv<MAX_SITECING_SCOREBOARD_SLOTS;rv++)
+ if( (slots[rv].state!=scoreboard_slot::state_free) && (slots[rv].pid == pid) )
+ return rv;
+ throw konforka::exception(CODEPOINT,"no such process");
+ }
+
+ int scoreboard::count_slots(enum scoreboard_slot::_state state) {
+ int rv = 0;
+ for(int tmp=0;tmp<MAX_SITECING_SCOREBOARD_SLOTS;tmp++) {
+ if(slots[tmp].state==state)
+ rv++;
+ }
+ return rv;
+ }
+
+}