0

i am trying to implement some custom lock-free structures. its operates similar to a stack so it has a take() and a free() method and operates on pointer and underlying array. typically it uses optimistic conncurrency. free() writes a dummy value to pointer+1 increments the pointer and writes the real value to the new address. take() reads the value at pointer in a spin/sleep style until it doesnt read the dummy value and then decrements the pointer. in both operations changes to the pointer are done with compare and swap and if it fails, the whole operation starts again. the purpose of the dummy value is to insure consistency since the write operation can be preempted after the pointer is incremented.

this situation leads me to wonder weather it is possible to prevent preemtion in that critical place by somhow determining how much time is left before the thread will be preempted by the scheduler for another thread. im not worried about hardware interrupts. im trying to eliminate the possible sleep from my reading function so that i can rely on a pure spin.

is this at all possible? are there other means to handle this situation?

EDIT: to clarify how this may be helpful, if the critical operation is interrupted, it will effectively be like taking out an exclusive lock, and all other threads will have to sleep before they could continue with their operations

EDIT: i am not hellbent on having it solved like this, i am merely trying to see if its possible. the probability of that operation being interrupted in that location for a very long time is extremely unlikely and if it does happen it will be OK if all the other operations need to sleep so that it can complete.

some regard this as premature optimization, but this is just my pet project. regardless - that does not exclude research and sience from attempting to improve techniques. even though computer sience has reasonably matured and every new technology we use today is just an implementation of what was already known 40 years ago, we should not stop to be creative to address even the smallest of concerns, like trying to make a reasonable set of operations atomic woithout too much performance implications.

Lawrence Ward
  • 549
  • 1
  • 5
  • 17
  • I would not do it in any real code but you could do a Sleep(0) prior to the critical code to ensure that it is done at the start of a time-slice as long as you are not concerned about the performance hit. – Jim Rhodes Jul 18 '13 at 21:03
  • 'prevent preemtion in that critical place by somhow determining how much time is left before the thread will be preempted by the scheduler for another thread. im not worried about hardware interrupts' the requirement and statement are internally inconsistent. It's a preemptive multitasker, if you are not worried by hardware interrupts, what are you worried by ? – Martin James Jul 18 '13 at 23:35
  • To put it another way, you want some way of anticipating the user clicking a mouse button, the NIC signaling the arrival of a packet and a disk-read completion. Good luck with that... – Martin James Jul 18 '13 at 23:38
  • Do you really have contention that matters on such a miniscule operation? Because if you don't, the extra overhead of needing multiple compare-and-swap operations (versus one for a lock) will make this a losing proposition. – David Schwartz Jul 19 '13 at 00:35
  • @MartinJames a normal hardware interrupt presumably should finish quite quickly. relatively, a usertask's timeslice is much longer, and theres not just one that scheduled but a few before the interrupted one gets time again. – Lawrence Ward Jul 19 '13 at 07:20
  • @JimRhodes does have the right idea, except that i dont want to call sleep if i kan know that i wont be interrupted for other user code to be scheduled any time soon – Lawrence Ward Jul 19 '13 at 07:22

2 Answers2

0

Cnnot be done without time-travel. You're stuffed.

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • isnt there a variable hidden in some obscure place in the TEB or other place in the kernel? how does the kernel know when to preempt schedule another user task? doesnt it maybe record a start time when the thread started its slice? anything? – Lawrence Ward Jul 19 '13 at 07:34
0

Such information surely exists somewhere, but it is of no use for you.

Under "normal conditions", you can expect upwards of a dozen DPCs and upwards of 1,000 interrupts per second. These do not respect your time slices, they occur when they occur. Which means, on the average, you can expect 15-16 interrupts within a time slice.

Also, scheduling does not strictly go quantum by quantum. The scheduler under present Windows versions will normally let a thread run for 2 quantums, but may change its opinion in the middle if some external condition changes (for example, if an event object is signalled).

Insofar, even if you know that you still have so and so many nanoseconds left, whatever you think you know might not be true at all.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • if you have pointers on where i can dig for 'such information' it will be useful. – Lawrence Ward Jul 19 '13 at 11:22
  • 1
    Well, at the very end of the TEB, you find two 64-bit values `LastSwitchTime` and `TotalSwitchOutTime`. You could use trap 0x2a (KiGetTickCount), and compare that to `LastSwitchTime` plus the length of a scheduler quantum (`timeBeginPeriod`). But, again, _this is not going to help you in any way_. Your thread will **still** be interrupted at unpredictable times. The only way of preventing this is to give it realtime priority, and that is an utterly bad idea, especially for spinning code. All you'll gain is having a dysfunct mouse and maybe disk errors... – Damon Jul 19 '13 at 11:46
  • Generally, threads must be prepared to be, _and will be_ interrupted at unpredictable times, and that is a good thing. It is the only way to ensure that external time critical tasks (disk finished reading, network card is ready, user moved the mouse) can be handled in a way so "things work normally". – Damon Jul 19 '13 at 11:50